it-swarm.com.de

Objekte in JavaScript löschen

Ich bin ein bisschen verwirrt mit dem delete -Operator von JavaScript. Nehmen Sie den folgenden Code:

var obj = {
    helloText: "Hello World!"
};

var foo = obj;

delete obj;

Nachdem dieser Code ausgeführt wurde, ist objnull, aber foo verweist immer noch auf ein Objekt genau wie obj. Ich vermute, dieses Objekt ist dasselbe Objekt, auf das foo zeigte.

Das verwirrt mich, weil ich erwartet habe, dass das Schreiben von delete obj löschte das Objekt, auf das obj im Speicher zeigte - nicht nur die Variable obj.

Liegt es daran, dass der Garbage Collector von JavaScript auf Retain-/Release-Basis arbeitet, sodass, wenn keine anderen Variablen auf das Objekt verweisen, es würde aus dem Speicher entfernt wird?

(Meine Tests wurden übrigens in Safari 4 durchgeführt.)

351
Steve Harrison

Der Operator delete löscht nur eine Referenz, niemals ein Objekt. Wenn es das Objekt selbst löschen würde, würden andere verbleibende Referenzen baumeln, wie ein C++ - Löschvorgang. (Wenn Sie auf eines dieser Objekte zugreifen, führt dies zu einem Absturz. Wenn Sie alle auf Null setzen, bedeutet dies, dass Sie zusätzliche Arbeit beim Löschen oder zusätzlichen Speicher für jedes Objekt benötigen.)

Da es sich bei Javascript um Müll handelt, müssen Sie Objekte nicht selbst löschen. Sie werden entfernt, wenn es keine Möglichkeit mehr gibt, auf sie zuzugreifen.

Es kann nützlich sein, Verweise auf ein Objekt zu löschen, wenn Sie damit fertig sind, da dies dem Garbage Collector mehr Informationen darüber gibt, was zurückgefordert werden kann. Verbleiben Verweise auf ein großes Objekt, kann dies dazu führen, dass es nicht mehr beansprucht wird - auch wenn der Rest Ihres Programms dieses Objekt nicht tatsächlich verwendet.

440
Jesse Rusak

Der Befehl delete hat keine Auswirkungen auf reguläre Variablen, nur auf Eigenschaften. Nach dem Befehl delete hat die Eigenschaft nicht den Wert null, sie existiert überhaupt nicht.

Wenn die Eigenschaft eine Objektreferenz ist, löscht der Befehl delete die Eigenschaft, jedoch nicht das Objekt. Der Garbage Collector kümmert sich um das Objekt, wenn er keine anderen Verweise darauf hat.

Beispiel:

var x = new Object();
x.y = 42;

alert(x.y); // shows '42'

delete x; // no effect
alert(x.y); // still shows '42'

delete x.y; // deletes the property
alert(x.y); // shows 'undefined'

(Getestet in Firefox.)

157
Guffa

"Implizit deklarierte Variablen" sind Eigenschaften des globalen Objekts. Löschen funktioniert also mit ihnen genauso wie mit jeder anderen Eigenschaft. Mit var deklarierte Variablen sind unzerstörbar.

54
Alex

Aus der Mozilla-Dokumentation: "Sie können den Operator delete verwenden, um implizit deklarierte Variablen zu löschen, aber nicht die, die mit der Anweisung var deklariert wurden."

Hier ist der Link: https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Operators:Special_Operators:delete_Operator

23
David Ackerman

basierend auf der Antwort von @Guffa. Ich fand die folgende Methode funktioniert für mich:

var obj = {
    helloText: "Hello World!"
};

obj = null;

delete obj;

Indem Sie das Objekt zuerst auf null setzen, haben Sie alle Verweise darauf entfernt und können es dann vollständig löschen.

Ich habe es nicht mit einem anderen Browser getestet, aber das funktioniert in phonegap 1.7.0

6
Bohr

delete wird nicht zum Löschen eines Objekts in Java Script verwendet.

delete zum Entfernen eines object key in deinem Fall

var obj = { helloText: "Hello World!" }; 
var foo = obj;
delete obj;

Objekt wird nicht gelöscht, prüfe ob noch gleiche Werte vorhanden sind lösche Verwendung:

delete obj.helloText

und dann überprüfe obj, foo, beide sind leere Objekte.

4
Umair Ahmed

Abgesehen von den GC-Fragen sollte man für die Leistung die Optimierungen berücksichtigen, die der Browser möglicherweise im Hintergrund vornimmt ->

http://coding.smashingmagazine.com/2012/11/05/writing-fast-memory-efficient-javascript/

Es scheint, als ob es besser wäre, die Referenz auf null zu setzen, als sie zu löschen, da dies die Verwendung der "Klasse" im Hintergrund verändern könnte Chrome).

2
sksizer

Ich habe gerade ein jsperf gefunden, das Sie im Lichte dieser Angelegenheit für interessant halten könnten. (Es könnte praktisch sein, es zu behalten, um das Bild zu vervollständigen)

Es vergleicht Löschen , Setzen Null und Setzen undefined .

Beachten Sie jedoch, dass dies den Fall testet, wenn Sie eine Eigenschaft mehrmals löschen/setzen.

2
garek

IE 5 bis 8 hat einen Fehler, bei dem die Verwendung von delete für Eigenschaften eines Host-Objekts (Window, Global, DOM usw.) TypeError auslöst "Objekt unterstützt diese Aktion nicht".

var el=document.getElementById("anElementId");
el.foo = {bar:"baz"};
try{
    delete el.foo;
}catch(){
    //alert("Curses, drats and double double damn!");
    el.foo=undefined; // a work around
}

Wenn Sie später überprüfen müssen, wo die Eigenschaft einen vollen Bedeutungswert hat, verwenden Sie el.foo !== undefined da "foo" in el gibt im IE immer true zurück.

Wenn Sie wirklich das Eigentum brauchen, um wirklich zu verschwinden ...

function hostProxy(Host){
    if(Host===null || Host===undefined) return Host;
    if(!"_hostProxy" in Host){
       Host._hostproxy={_Host:host,prototype:Host};
    }
    return Host._hostproxy;
}
var el=hostProxy(document.getElementById("anElementId"));
el.foo = {bar:"baz"};

delete el.foo; // removing property if a non-Host object

wenn Sie das Host-Objekt mit Host-API verwenden müssen ...

el.parent.removeChild(el._Host);
1
johndhutcheson

Bei meiner Suche nach der gleichen Antwort bin ich über diesen Artikel gestolpert. Am Ende habe ich nur obj.pop() alle gespeicherten Werte/Objekte in meinem Objekt ausgelesen, damit ich das Objekt wiederverwenden kann. Ich bin mir nicht sicher, ob dies eine schlechte Übung ist oder nicht. Diese Technik hat sich als nützlich erwiesen, wenn ich meinen Code in Chrome Dev Tools oder FireFox Web Console) getestet habe.

1
Craig London

Diese Arbeit für mich, obwohl es keine gute Praxis ist. Es werden einfach alle Elemente gelöscht, zu denen das Objekt gehört.

 for (element in homeService) {
          delete homeService[element];
  }
1
vineet sagar

Wenn Sie eine Variable auf null setzen, werden alle Verweise auf Objekte in allen Browsern aufgehoben, einschließlich Zirkelverweise, die zwischen den DOM-Elementen und Javascript-Bereichen erstellt werden. Mit dem Befehl delete markieren wir Objekte, die beim nächsten Durchlauf der Garbage-Auflistung gelöscht werden sollen. Wenn jedoch mehrere Variablen auf dasselbe Objekt verweisen, wird das Objekt durch Löschen einer einzelnen Variablen NICHT freigegeben, sondern nur entfernt die Verknüpfung zwischen dieser Variablen und dem Objekt. Und beim nächsten Durchlauf der Garbage-Auflistung wird nur die Variable bereinigt.

0
Pedro Justo