|
|||
Prüfen, ob eine Eigenschaft ein Setter ist
Hallo,
ich suche eine Möglichkeit, herauszufinden, ob eine Eigenschaft eines Objektes ein Setter ist. Motivation: Ich habe ein JS-Modul, das recht komplex ist und unter Umständen viele Objekte erzeugt, die aber nicht unbedingt bis zum verlassen der Seite erhalten bleiben. Da es in JavaScript keine Destruktoren gibt, und ich nur schwer sicherstellen kann, dass keine Referenzen mehr auf ein Objekt existieren, sodass dieses vom Garbage Collector eingesammelt werden kann, habe ich mir einfach eine eigene free-Methode geschrieben, deren letzte Zeile lautet: Code:
try { for (var key in Object.keys(this)) delete this[key]; } catch (e) {} for (var key in this) this[key] = undefined; Nun gibt es das Problem, dass Eigenschaften des Prototypes nicht gelöscht werden können. Ich kann diese nur mit undefined überschreiben. Handelt es sich bei einer dieser Eigenschaften um einen Setter, so wird nicht der Setter überschrieben, sondern eben die Setter-Funktion aufgerufen, was zu Fehlern führen kann. Also wie kann ich überprüfen, ob eine Eigenschaft ein Setter ist und wenn ja, diesen überschreiben? |
Sponsored Links |
|
|||
Nun, der Garbage Collector kann das Objekt ja nur dann freigeben, wenn keine Referenz mehr darauf existiert. Und ich habe über 2000 Zeilen an Code, der zum Teil recht komplex verschachtelt ist... Da kommt es manachmal eben vor, dass man eine Referenz übersieht. Eine free-Prozedur brauche ich sowieso, da ja die EventListener freigegeben werden müssen, die das Objekt gesetzt hat. Auch "betreut" ein Objekt verschiedene HTML-Elemente, die in free aus dem DOM entfernt werden. Ohne diese Elemente und die EventListener erfüllt das Objekt seinen Zweck nicht mehr richtig, es treten auch Fehler auf, wenn die Elemente nicht mehr im DOM sind. Da ist es naheliegend, auch alle Funktionen und Eigenschaften zu löschen. So erleichtere ich dem Garbage Collector die Arbeit und finde unnötige Referenzen schneller.
Auf jeden Fall funktioniert das Ganze sehr zufriedenstellend, nur die Getter und Setter machen mir Ärger. Aber darauf zu verzichten wäre genau so doof. |
|
||||
Zitat:
Wir reden über JS, nicht über C/C++, da kannst du keine Referenzen übersehen. Zitat:
Das sind alles Standardabläufe, die für einen GC in dynamischen Programmiersprachen die Grundlage bedeuten. Wenn er das nicht beherrscht, verdient er den Namen nicht. Es gab aber in älteren IEs Probleme damit. Aber soweit ich das seh war das nur bis IE 8 so und die anderen Browser hatten damit keine Probleme. Und das betraf nur ganz spezielle Fälle, die auch nur ganz spezille Workarouns brauchten. JavaScript and memory leaks Memory Leaks Ich kenne auf jeden Fall kein Framework, dass sich die Arbeit machen würde eine zusätzliche Speicherverwaltung über die eigentliche zu bauen und z.b. ExtJS macht auch sehr viel von dem was du da beschriebst und die kommen auch ohne aus. |
|
|||
Ich meinte auch nicht, dass der GC etwas übersieht, sondern ich.
Also konkret geht es um mein JS Windows-Projekt: JS Windows Jedes Fenster hat ein Objekt/ist ein Objekt. Und nach dem schließen des Fensters soll dieses freigegeben werden. Nun kann man aber an allen möglichen Stellen (das schließt z.B. auch andere IFrames ein) Referenzen auf ein Fensterobjekt speichern und es ist eben nicht ganz einfach, sicherzustellen, dass die alle nach free gelöscht werden. Denn der Zugriff auf ein geschlossenes Fenster ist zum Beispiel möglich (vorgesehen), denn einige Fenster müssen wiederherstellbar sein. Würde ich also auf ein explizites Freigeben verzichten, wäre im Prinzip jedes Fenster wiederherstellbar und würde samt HTML-Elementen im Speicher bleiben, solange irgendwo noch eine Referenz übrig ist. Außerdem wäre eine Methode, um festzustellen, ob eine Eigenschaft ein Setter ist, auch an anderer Stelle hilfreich, z.B. beim Klonen von Objekten. Damit hatte ich auch so meine Schwierigkeiten... |
|
|||
Ich meine so etwas:
Code:
JSWindow.prototype = { [...] _maximizable : true, get maximizable () { return this._maximizable; }, set maximizable (v) { this._maximizable = v; this.setOrRmAtr(this.el['Buttons'], 'nonmaximizable', !v); }, [...] } Ob ein Fenster nach dem schließen freigegeben werden soll, entscheidet die Eigenschaft freeOnHide. In der Regel ist diese true. Wenn nach free noch Referenzen auf das Objekt existieren, sollen diese nicht mehr benutzbar sein. Zum Beispiel gibt es verschiedene Möglichkeiten, ein Fenster zu erstellen. Das kann zum Beispiel so aussehen: Code:
var w = new JSWindow(); w.maximizable = false; PS: Übrigens habe ich gerade den von dir verlinkten Text zu Memmory Leaks angesehen und der bestätigt eigentlich nur, was ich immer vermutet habe. Ich behaupte mal, es gibt keine Programmier/Scriptsprache, bei der Garbage Collection so schwierig ist, wie in JavaScript. Allein schon, wann ein Funktionsscope freigegeben werden kann: Wenn die Funktion fertig ist? Nein, Funktionsvariablen können ja auch von EventListenern, die in dieser Funktion gesetzt wurden, aber erst nach deren Beendigung aufgerufen werden, gelesen werden... Und bei meinem Projekt können eben durchaus zyklische Referenzierungen zwischen mehreren Fenstern auftreten, über EventListener, Funktionsscopes, deren Funktion schon beendet ist, und das noch frameübergreifend (und sogar Seitenübergreifend - manche Fenster lassen sich in ein Popup verwandeln, zum Beispiel die Dokumentationsseite zu JS Windows, indem man den Button links neben dem zum minimieren anklickt). Dass das jeder Browser schafft, bezweifele ich. Deswegen kann es nicht schaden, das ganze mit free ein bisschen aufzurütteln... Geändert von MitjaStachowiak (13.12.2014 um 02:54 Uhr) |
|
||||
Zitat:
Noch mal, das was du beschreibst sind seit Jahrtzehnten die üblichen Aufgaben der GC in Javascript (und anderen dynamischen Sprachen - in Perl sieht die Sache nicht anders aus) und bisher lösen JS Engines diese Aufgabe sehr gut - die einzige Auffällige Ausnahme waren alte Versionen des IEs. Da "von Hand" dran rumschruaben zu wollen ist unötiger Unsinn. |
|
||||
Zitat:
Wenn in deinem Code dadurch ein Problem auftaucht, dass du eine öffentliche Eigenschaft änderst, dann darfst du diese nicht öffentlich machen. Das hat aber nichts mit der Speicherverwaltung zu tun. Wie gesagt, die Browser haben kein Problem mit der Speicherverwaltung, das was du beschreibst klingt eher nach einem Problem in der Logik deiner Anwendung. |
Sponsored Links |
|
||||
Oder mal ein paar Zitate aus Fachquellen:
Writing Fast, Memory-Efficient JavaScript - Smashing Magazine Zitat:
Zitat:
Und die Tipps sagen es ganz klar, DU musst darauf achten, dass Objekte nicht unötig lange aufbewahrt werden. Zitat:
und noch mehr: https://developer.chrome.com/devtool...mory-profiling Der Punkt ist, um Speicherlöcher zu vermeiden ist es wichtig, den Scope zu löschen, also z.b. die Event- oder Timerfunktion, damit die dort enthaltenen Objekte auch aufgeräumt werden können. Es bringt aber nichts die Objekte selbst zu löschen, solange noch irgendwo Referenzen existieren werden diese nicht von dem GC entfernt. Oder mal ein Beispiel. Das Element (el) existiert bis zum Schluss, egal ob du es aus dem DOM entfernst oder das Objekt nullst oder die getter Funktion entfernst. HTML-Code:
<div id="test">test</div> <script type="text/javascript"> var main_f = ( function() { var el = document.getElementById('test'); function Obj(el){ this.get = function() { return el;}; this.toString = function() { return el + ''; }; } var o = new Obj(el); document.body.removeChild(el); el = null; var ret = (function(x) { return function() { alert('existiert das Element noch: ' + x); alert('aber o.get : ' + x.get); }; })(o); delete o.get; o = null; return ret; })(); (function() { main_f(); window.setTimeout(main_f, 1000); })(); </script> |
Sponsored Links |
Stichwörter |
auf setter prüfen, setter erkennen, setter löschen, setter übberschreiben |
Themen-Optionen | |
Ansicht | |
|
|
Ähnliche Themen | ||||
Thema | Autor | Forum | Antworten | Letzter Beitrag |
Redesign für Steiner Cycling Team | pkipper | Site- und Layoutcheck | 11 | 09.02.2011 13:25 |
Prüfen, ob Popup noch existiert | xm22 | Javascript & Ajax | 1 | 28.06.2010 18:41 |
Prüfen ob String HTML Code enthält | meGa | Serveradministration und serverseitige Scripte | 3 | 06.05.2009 17:54 |
Geerbte Eigenschaft löschen | getit | CSS | 3 | 27.01.2009 12:04 |
Eigenschaft einer Klasse selektiv überschreiben | subbz2k | CSS | 12 | 02.04.2008 16:32 |