Usuwanie obiektów w JavaScript

Jestem trochę zmieszany z operatorem delete JavaScript. Weź następujący fragment kodu:

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

var foo = obj;

delete obj;

Po wykonaniu tego fragmentu kodu, obj jest null, ale foo nadal odnosi się do obiektu dokładnie takiego jak obj. Zgaduję, że ten obiekt jest tym samym obiektem, na który wskazała foo.

To mnie myli, ponieważ spodziewałem się, że zapis delete obj usunie obiekt, na który obj wskazywał w pamięci-a nie tylko zmienną obj.

Czy to dlatego, że JavaScript jest Garbage Collector działa na zasadzie retain/release, więc gdybym nie miał żadnych innych zmiennych wskazujących na obiekt, to czy zostanie usunięty z pamięci?

(przy okazji, moje testy zostały wykonane w Safari 4.)

Author: Sam, 2009-04-13

12 answers

Operator delete usuwa tylko odniesienie, nigdy sam obiekt. Gdyby usunął sam obiekt, inne pozostałe odniesienia byłyby zwisające, jak C++ delete. (A dostęp do jednego z nich spowodowałby awarię. Aby wszystkie zamieniły się w null, oznaczałoby to dodatkową pracę przy usuwaniu lub dodatkową pamięć dla każdego obiektu.)

Ponieważ Javascript jest garbage collected, nie musisz usuwać obiektów samodzielnie - zostaną one usunięte, gdy nie ma już sposobu, aby się do nich odwoływać.

Przydatne może być usunięcie odniesień do obiektu, jeśli już je ukończyłeś, ponieważ daje to garbage collector więcej informacji o tym, co można odzyskać. Jeśli odwołania pozostają do dużego obiektu, może to spowodować jego nieodebranie - nawet jeśli reszta programu nie używa tego obiektu.

 422
Author: Jesse Rusak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-13 01:34:45

Polecenie delete nie ma wpływu na zmienne zwykłe, tylko na właściwości. Po poleceniu delete właściwość nie ma wartości null, w ogóle nie istnieje.

Jeśli właściwość jest odniesieniem do obiektu, polecenie delete usuwa właściwość, ale nie obiekt. Garbage collector zajmie się obiektem, jeśli nie ma do niego innych odniesień.

Przykład:

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'

(Testowane w Firefoksie.)

 152
Author: Guffa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-12 23:39:51

"zmienne zadeklarowane domyślnie" są właściwościami obiektu globalnego, więc delete działa na nich tak, jak na dowolnej właściwości. Zmienne zadeklarowane przez var są niezniszczalne.

 52
Author: Alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-13 20:54:59

Pochodzące z Dokumentacji Mozilli, " możesz użyć operatora delete, aby usunąć zmienne zadeklarowane domyślnie, ale nie te zadeklarowane za pomocą instrukcji var. "

Oto link: https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Operators:Special_Operators:delete_Operator

 23
Author: David Ackerman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-12 23:42:55

Na podstawie odpowiedzi @Guffa. Znalazłem następującą metodę działa dla mnie:

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

obj = null;

delete obj;

Ustawiając obj na null Najpierw usunąłeś wszystkie odniesienia do niego, a następnie możesz usunąć je całkowicie.

Nie testowałem go na innej przeglądarce, ale działa to w phonegap 1.7.0

 7
Author: Bohr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-21 06:56:07

delete nie jest używany do usuwania obiektu w java Script.

delete używany do usuwania object key w Twoim przypadku

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

obiekt nie jest usuwany sprawdź obj nadal przyjmuj te same wartości Usuń użycie:

delete obj.helloText

A następnie zaznacz obj, foo, oba są pustymi obiektami.

 4
Author: Umair Ahmed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-20 09:40:12

Właśnie znalazłem jsperf możesz uznać za interesujące w świetle tej sprawy. (może być przydatny do trzymania go w pobliżu, aby zakończyć obraz)

porównuje delete, setting null i setting undefined.

Ale należy pamiętać, że testuje przypadek, gdy usuniesz/ustawisz właściwość wiele razy.

 2
Author: garek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-12 17:17:00

Poza pytaniami GC, dla wydajności należy wziąć pod uwagę optymalizacje, które przeglądarka może wykonywać w tle - >

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

Wydaje się, że lepiej jest anulować odniesienie niż je usunąć, ponieważ może to zmienić kulisy 'klasy' używanej przez Chrome.

 2
Author: sksizer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-18 12:25:03

IE od 5 do 8 ma błąd, w którym użycie delete we właściwościach obiektu hosta (Window, Global, DOM itp.) wyrzuca TypeError "object does not support this action".

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
}

Później, jeśli chcesz sprawdzić, gdzie właściwość ma znaczenie, użyj el.foo !== undefined, Ponieważ "foo" in el zawsze powróci true w IE.

Jeśli naprawdę potrzebujesz własności, aby naprawdę zniknąć...

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

Jeśli potrzebujesz użyć obiektu host Z host api...

el.parent.removeChild(el._host);
 1
Author: johndhutcheson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-17 22:18:41

Natknąłem się na ten artykuł w moim poszukiwaniu tej samej odpowiedzi. To, co zrobiłem, to wyskakiwanie obj.pop() wszystkich przechowywanych wartości / obiektów w moim obiekcie, abym mógł go ponownie użyć. Nie wiem, czy to zła praktyka, czy nie. Ta technika przydała mi się podczas testowania kodu w Chrome Dev tools lub FireFox Web Console.

 0
Author: Craig London,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-04 07:30:13

Ustawienie zmiennej na null powoduje przerwanie wszelkich odniesień do obiektów we wszystkich przeglądarkach, w tym odniesień okrągłych między elementami DOM i zakresami Javascript. Za pomocą polecenia delete zaznaczamy obiekty, które mają zostać wyczyszczone przy następnym uruchomieniu Garbage collection, ale jeśli istnieje wiele zmiennych odwołujących się do tego samego obiektu, usunięcie jednej zmiennej nie uwolni obiektu, po prostu usunie powiązanie między tą zmienną a obiektem. I w następnym biegu ze zbioru śmieci zostanie wyczyszczona tylko zmienna.

 0
Author: Pedro Justo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-18 10:36:23

To działa dla mnie, chociaż nie jest to dobra praktyka. To po prostu usunąć wszystkie powiązany element, do którego należy obiekt.

 for (element in homeService) {
          delete homeService[element];
 0
Author: vineet sagar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-26 17:36:11