mmofacts.com

Weak refs/Closures in Javascript?

gepostet vor 17 Jahre, 1 Monat von COrthbandt
Kennt irgendjemand einen Weg, closures in Javascript so zu gestalten, dass sie keine Zirkelreferenzen erzeugen?
Beispiel:

function Test()
{
var xThis=this;
this.Foobar=function()
{
this.m_xButtonEl.innerHTML="foobar";
};
this.m_xButtonEl=document.createElement("a");
this.m_xButtonEl.innerHTML="blahfasel";
this.m_xButtonEl.onclick=function(){
xThis.Foobar();
};
document.body.appendChild(this.m_xButtonEl);
return this;
};
g_xMyButton=new Test();
Das Problem ist, dass das DOM-Element eine direkte Referenz auf das JS-Element hält und umgekehrt. In diesem stark vereinfachten Beispiel ginge das natürlich auch anders, aber in real world code tritt doch öfter (u.U. getarnt) dieses Konstrukt auf (mit RPCs z.B.).
Es führt bei verschiedenen Browsern zu Leaks, weil DOM und JS getrennte GC haben.
Kennt nun irgendjemand eine Möglichkeit soetwas wie "weak references" in JS zu simulieren (in JS 2.0 scheint "weak" vorgesehen zu sein)?
Diesen Hack hier:
laurens.vd.oever.nl/weblog/items2005/closures/
kenne ich schon, eine globale Registry aller closures ist irgendwie keine performante Lösung.
gepostet vor 17 Jahre, 1 Monat von Todi42
Vielleicht ist es in Deinem Fall praktikabel, die DOM-Elemente über ihre ID zu referenzieren?
gepostet vor 17 Jahre, 1 Monat von COrthbandt
Das hilft nicht wirklich, da mein Problem ja nicht das DOM-Element ist, sondern das JS-Objekt. Und das hat halt naturgemäß keine ID und wird daher vom DOM referenziert.
Edit: Also natürlich KANN man alle JS-Objects in einer globalen Tabelle mit IDs versehen, aber genau das will ich ja vermeiden.
gepostet vor 17 Jahre, 1 Monat von Todi42

function Test()
{
var xThis=this;
this.Foobar=function()
{
$(this.button_id).innerHTML="foobar";
};
var m_xButtonEl=document.createElement("a");
m_xButtonEl.innerHTML="blahfasel";
m_xButtonEl.onclick=function(){
xThis.Foobar();
};
m_xButtonEl.id = create_global_id();
this.button_id = m_xButtonEl.id;
document.body.appendChild(m_xButtonEl);
return this;
};

$() ist an prototype.js angeleht und entspricht getElementByID oder so ähnlich. create_global_id() wäre eine Funktion, die z.B. einen globalen Integer inkrementiert und daraus dann einen eindeutigen Namen macht.
Aus einem aktuellen thread aus de.comp.lang.javascript habe ich aber gelesen, das das setzen einer ID bei Elementen, die mit createElement() erzeugt wurden mit dem IE so nicht funktioniert (es existiert aber ein workaround).
gepostet vor 17 Jahre, 1 Monat von COrthbandt
Die id auf dem DOM-Element zu setzen ist kein Problem. Das Problem ist das JS-Objekt und die Referenz, die vom DOM nach JS zeigt.
Die Sache wird komplizierter, wenn wir mal das einfache DOM-Element vergessen und an XmlHTTPRequest denken. Da habe ich gar kein document, dass die IDs verwaltet.
Und ich würde eben gerne vermeiden, alle Objekte in einer globalen Map zu halten. Das ist ja im Grunde das, was der oben angeführte Hack macht.
gepostet vor 17 Jahre, 1 Monat von Teonas
Ich habe mich mit dem Thema auch ausgiebiger beschäftigt und alle Lösungen des Problems, die ich gefunden habe, wenden einen Manager für Eventhandler (das ist ja die Crux) an und entsorgen die Referenzen dann. Bei der Menge von Lösungen, die ich mir angeschaut habe (so um ein Dutzend) wage ich zu vermuten, wer die Lösung kennt, zahlt viel, dass sie geheim bleibt - vermutlich gibt es aber keine andere

Auf diese Diskussion antworten