Удаление объектов в JavaScript

Я немного запутался с оператором JavaScript delete. Возьмите следующий фрагмент кода:

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

var foo = obj;

delete obj;

После выполнения этой части кода obj есть null, но foo все равно относится к объекту, точно как obj. Я предполагаю, что этот объект является тем же объектом, на который указывает foo.

Это меня смущает, потому что я ожидал, что запись delete obj удалит объект, на который obj указывал в памяти, а не только переменную obj.

Это потому, что JavaScript Garbage Collector работает на основе сохранения/выпуска, так что если бы у меня не было других переменных, указывающих на объект, оно было бы удалено из памяти?

(Кстати, мое тестирование было выполнено в Safari 4.)

Ответ 1

Оператор delete удаляет только ссылку, а не сам объект. Если бы он удалил сам объект, другие оставшиеся ссылки были бы свисающими, например, С++ delete. (И доступ к одному из них приведет к сбою. Для того, чтобы все они обменивались с нулем, это означало бы наличие дополнительной работы при удалении или дополнительной памяти для каждого объекта.)

Поскольку Javascript - сбор мусора, вам не нужно удалять объекты сами - они будут удалены, когда больше не будет ссылок на них.

Может быть полезно удалить ссылки на объект, если вы закончили с ними, потому что это дает сборщику мусора дополнительную информацию о том, что можно вернуть. Если ссылки остаются на большом объекте, это может привести к его невосстановлению - даже если остальная часть вашей программы фактически не использует этот объект.

Ответ 2

Команда delete не влияет на обычные переменные, а только на свойства. После команды delete свойство не имеет значения null, оно вообще не существует.

Если свойство является ссылкой на объект, команда delete удаляет свойство, но не объект. Сборщик мусора позаботится об объекте, если у него нет других ссылок на него.

Пример:

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'

(Протестировано в Firefox.)

Ответ 3

"переменные, объявленные неявно", являются свойствами глобального объекта, поэтому удаление работает над ними, как будто оно работает с любым свойством. Переменные, объявленные с помощью var, нерушимы.

Ответ 5

на основе ответа @Guffa. Я нашел, что для меня работает следующий метод:

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

obj = null;

delete obj;

Сначала задав объект obj null, вы удалили всю ссылку на него, затем вы можете полностью удалить его.

Я не тестировал его в другом браузере, но это работает в phonegap 1.7.0

Ответ 6

delete не используется для удаления объекта в Java Script.

delete используется для удаления object key в вашем случае

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

объект не удален проверить объект все еще принимать те же значения удалить использование:

delete obj.helloText

и затем проверьте obj, foo, оба являются пустым объектом.

Ответ 7

Помимо вопросов GC, для производительности следует учитывать оптимизацию, которую браузер может выполнять в фоновом режиме →

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

Кажется, что было бы лучше сбросить ссылку, чем удалить ее, поскольку это может изменить класс за кадром, используемый Chrome.

Ответ 8

Просто нашел jsperf, который может показаться интересным в свете этого вопроса. (было бы удобно держать его вокруг, чтобы завершить изображение)

Он сравнивает удалять, устанавливая null и устанавливая undefined.

Но имейте в виду, что он проверяет случай, когда вы удаляете/устанавливаете свойство много раз.

Ответ 9

IE 5-8 имеет ошибку, в которой использование delete по свойствам объекта-хозяина (Window, Global, DOM и т.д.) вызывает объект TypeError, который не поддерживает это действие.

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
}

Позже, если вам нужно проверить, где свойство имеет значение полного значения, используйте el.foo !== undefined, потому что "foo" in el всегда будет возвращать true в IE.

Если вам действительно нужно свойство, чтобы действительно исчезнуть...

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

если вам нужно использовать объект-хост с host api...

el.parent.removeChild(el._host);

Ответ 10

Я наткнулся на эту статью в своем поиске этого же ответа. То, что я закончил, - это просто вывести obj.pop() все сохраненные значения/объекты в моем объекте, чтобы я мог повторно использовать объект. Не уверен, что это плохая практика или нет. Этот метод оказался полезным для тестирования моего кода в инструментах Chrome Dev или в FireFox Web Console.

Ответ 11

Это работа для меня, хотя это не очень хорошая практика. Он просто удаляет все связанные элементы, к которым принадлежит объект.

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

Ответ 12

Установка переменной в null позволяет обрывать любые ссылки на объекты во всех браузерах, включая круговые ссылки между элементами DOM и областями Javascript. Используя команду delete, мы отмечаем объекты, подлежащие очистке при следующем запуске коллекции Garbage, но если есть несколько переменных, ссылающихся на один и тот же объект, удаление одной переменной НЕ освобождает объект, он просто удалит связь между эту переменную и объект. И при следующем запуске коллекции мусора будет очищена только переменная.