Eliminar objetos en JavaScript


Estoy un poco confundido con el operador de JavaScript delete. Tome el siguiente fragmento de código:

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

var foo = obj;

delete obj;

Después de que esta pieza de código ha sido ejecutada, obj es null, pero foo todavía se refiere a un objeto exactamente como obj. Supongo que este objeto es el mismo objeto que foo señaló.

Esto me confunde, porque esperaba que escribir delete obj borrara el objeto al que obj apuntaba en la memoria, no solo la variable obj.

Es esto porque JavaScript El Recolector de basura está trabajando sobre una base de retención / liberación, de modo que si no tuviera ninguna otra variable apuntando al objeto, sería eliminado de la memoria?

(Por cierto, mi prueba se hizo en Safari 4.)

Author: Sam, 2009-04-13

12 answers

El operador delete borra solo una referencia, nunca un objeto en sí. Si eliminara el objeto en sí, otras referencias restantes estarían colgando, como una eliminación de C++. (Y acceder a uno de ellos causaría un accidente. Hacer que todos se vuelvan nulos significaría tener trabajo extra al eliminar o memoria extra para cada objeto.)

Dado que Javascript es basura recolectada, no es necesario eliminar los objetos por sí mismos, se eliminarán cuando ya no haya forma de referirse a ellos.

Puede ser útil eliminar referencias a un objeto si ha terminado con ellas, porque esto le da al recolector de basura más información sobre lo que puede ser reclamado. Si las referencias permanecen a un objeto grande, esto puede causar que no sea reclamado, incluso si el resto de su programa no usa ese objeto.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-13 01:34:45

El comando delete no tiene ningún efecto en las variables regulares, solo en las propiedades. Después del comando delete la propiedad no tiene el valor null, no existe en absoluto.

Si la propiedad es una referencia de objeto, el comando delete elimina la propiedad pero no el objeto. El recolector de basura se encargará del objeto si no tiene otras referencias.

Ejemplo:

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'

(Probado en Firefox.)

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-12 23:39:51

"variables declaradas implícitamente" son propiedades del objeto global, por lo que delete funciona en ellas como funciona en cualquier propiedad. Las variables declaradas con var son indestructibles.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-13 20:54:59

Viniendo de la Documentación de Mozilla, "Puede usar el operador delete para eliminar variables declaradas implícitamente pero no aquellas declaradas con la instrucción var. "

Aquí está el enlace: 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-12 23:42:55

Basado en la respuesta de @Guffa. Encontré que el siguiente método funciona para mí:

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

obj = null;

delete obj;

Al establecer el obj en null primero, eliminó toda la referencia a él, luego puede eliminarlo por completo.

No lo probé en otro navegador, pero esto funciona en 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-21 06:56:07

delete no se utiliza para eliminar un objeto en java Script.

delete se utiliza para eliminar un object key en su caso

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

object is not deleted check obj still take same values delete usage:

delete obj.helloText

Y luego marque obj, foo, ambos son objetos vacíos.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-20 09:40:12

Acabo de encontrar un jsperf que puede considerar interesante a la luz de este asunto. (podría ser útil mantenerlo alrededor para completar la imagen)

compara delete, configuración null y ajuste de indefinido.

Pero tenga en cuenta que prueba el caso cuando elimina la propiedad/set muchas veces.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-12 17:17:00

Aparte de las preguntas GC, para el rendimiento uno debe considerar las optimizaciones que el navegador puede estar haciendo en segundo plano- >

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

Parece que puede ser mejor anular la referencia que eliminarla, ya que puede cambiar el detrás de escena 'clase' Chrome utiliza.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-18 12:25:03

IE 5 a través de 8 tiene un error donde el uso de eliminar en las propiedades de un objeto host (Ventana, Global, DOM, etc.) lanza TypeError "objeto no soporta esta acción".

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
}

Más tarde, si necesita verificar dónde la propiedad tiene un valor completo de significado, use el.foo !== undefined porque "foo" in el siempre devolverá true en IE.

Si realmente necesita que la propiedad desaparezca realmente...

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

Si necesita usar el objeto host con la api host...

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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-17 22:18:41

Me topé con este artículo en mi búsqueda de esta misma respuesta. Lo que terminé haciendo es simplemente sacar obj.pop() todos los valores/objetos almacenados en mi objeto para poder reutilizar el objeto. No estoy seguro de si esto es una mala práctica o no. Esta técnica me fue muy útil para probar mi código en Chrome Dev tools o 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-04 07:30:13

Establecer una variable en null se asegura de romper cualquier referencia a objetos en todos los navegadores, incluidas las referencias circulares que se hacen entre los elementos DOM y los ámbitos Javascript. Al usar el comando delete estamos marcando objetos que se borrarán en la próxima ejecución de la colección de elementos no utilizados, pero si hay varias variables que hacen referencia al mismo objeto, eliminar una sola variable NO liberará el objeto, solo eliminará el enlace entre esa variable y el objeto. Y en la próxima carrera de la recolección de basura, solo se limpiará la variable.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-18 10:36:23

Este trabajo para mí, aunque no es una buena práctica. Simplemente eliminar todos los el elemento asociado al que pertenece el objeto.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-26 17:36:11