Excluindo Objetos em JavaScript

Estou um pouco confuso com o operador delete do JavaScript. Pegue o seguinte trecho de código:

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

Após este trecho de código ter sido executado, obj é null , mas foo ainda se refere a um object exatamente como obj . Eu estou supondo que este object é o mesmo object que foo apontado.

Isso me confunde, porque eu esperava que escrever delete obj deletesse o object que obj estava apontando na memory – não apenas a variável obj .

Isso ocorre porque o Garbage Collector do JavaScript está trabalhando em uma base de retenção / liberação, de modo que, se eu não tivesse outras variables ​​apontando para o object, ele seria removido da memory?

(By the way, meu teste foi feito no Safari 4.)

O operador delete exclui apenas uma referência, nunca um object em si. Se ele excluísse o object em si, outras referências restantes ficariam pendentes, como uma exclusão de C ++. (E acessar um deles causaria uma falha. Torná-los todos nulos significaria ter trabalho extra ao excluir ou extra memory para cada object.)

Como o Javascript é coletado como lixo, você não precisa excluir objects – eles serão removidos quando não houver mais como se referir a eles.

Pode ser útil excluir referências a um object se você tiver terminado com elas, porque isso fornece ao coletor de lixo mais informações sobre o que pode ser recuperado. Se as referências permanecerem em um object grande, isso pode fazer com que ele não seja reconhecido – mesmo que o resto do programa não use realmente esse object.

O comando delete não tem efeito sobre variables ​​regulares, apenas propriedades. Após o comando delete a propriedade não tem o valor null , não existe de todo.

Se a propriedade for uma referência de object, o comando delete excluirá a propriedade, mas não o object. O coletor de lixo cuidará do object se não tiver outras referências a ele.

Exemplo:

 var x = new Object(); xy = 42; alert(xy); // shows '42' delete x; // no effect alert(xy); // still shows '42' delete xy; // deletes the property alert(xy); // shows 'undefined' 

(Testado no Firefox.)

“variables ​​declaradas implicitamente” são propriedades do object global, portanto, delete funciona como se ele estivesse funcionando em qualquer propriedade. Variáveis ​​declaradas com var são indestrutíveis.

Vindo da documentação do Mozilla, “Você pode usar o operador delete para excluir variables ​​declaradas implicitamente, mas não aquelas declaradas com a instrução var.”

Aqui está o link: https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Operators:Special_Operators:delete_Operator

baseado na resposta do @Guffa. Eu encontrei o seguinte método funciona para mim:

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

Ao definir o obj como null primeiro, você removeu toda a referência a ele e, em seguida, pode excluí-lo completamente.

Eu não testei em outro navegador, mas isso funciona no phonegap 1.7.0

delete não é usado para excluir um object no java Script.

delete usado para remover uma object key no seu caso

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

object não é deletado check obj ainda toma os mesmos valores delete use:

 delete obj.helloText 

e então cheque obj, foo , ambos são objects vazios.

Acabei de encontrar um jsperf que você pode considerar interessante à luz deste assunto. (pode ser útil mantê-lo por perto para completar a foto)

Compara delete , definindo null e definindo indefinido .

Mas tenha em mente que ele testa o caso quando você exclui / define a propriedade várias vezes.

Além das perguntas do GC, para o desempenho, deve-se considerar as otimizações que o navegador pode estar fazendo em segundo plano ->

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

Parece que pode ser melhor anular a referência do que excluí-la, pois isso pode alterar a “class” usada pelo Chrome nos bastidores.

IE 5 a 8 tem um bug onde usando delete em propriedades de um object de host (Window, Global, DOM etc) lança TypeError “object não suporta esta ação”.

 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 } 

Posteriormente, se você precisar verificar onde a propriedade tem um valor completo de significado, use el.foo !== undefined porque "foo" in el sempre retornará true no IE.

Se você realmente precisa da propriedade para realmente desaparecer …

 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 

se você precisa usar o object host com api …

 el.parent.removeChild(el._host); 

Eu tropecei neste artigo na minha busca por essa mesma resposta. O que acabei fazendo foi apenas obj.pop() para fora obj.pop() todos os valores / objects armazenados em meu object para que eu pudesse reutilizar o object. Não tenho certeza se isso é uma má prática ou não. Essa técnica foi útil para eu testar meu código nas ferramentas do Chrome Dev ou no FireFox Web Console.

Definir uma variável como null garante a quebra de qualquer referência a objects em todos os navegadores, incluindo referências circulares feitas entre os elementos DOM e os escopos Javascript. Ao usar o comando delete , estamos marcando os objects a serem limpos na próxima execução da garbage collection, mas se houver várias variables ​​referenciando o mesmo object, a exclusão de uma única variável NÃO liberará o object, apenas removerá a vinculação entre essa variável e o object. E na próxima execução da garbage collection, apenas a variável será limpa.

Este trabalho para mim, embora não seja uma boa prática. Ele simplesmente exclui todo o elemento associado ao qual o object pertence.

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