lista - Eliminar objetos en JavaScript
lista de objetos javascript (12)
Estoy un poco confundido con el operador de delete
de JavaScript. Toma el siguiente código:
var obj = {
helloText: "Hello World!"
};
var foo = obj;
delete obj;
Después de que se haya ejecutado este fragmento de código, obj
es null
, pero foo
aún 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 al escribir delete obj
eliminara el objeto que obj
estaba apuntando en la memoria, no solo la variable obj
.
¿Esto se debe a que el recolector de basura de JavaScript está trabajando para retener / liberar, de modo que si no tuviera ninguna otra variable que apunte al objeto, se eliminaría de la memoria?
(Por cierto, mi prueba se realizó en Safari 4).
"las variables declaradas implícitamente" son propiedades del objeto global, por lo que eliminar funciona en ellas como funciona en cualquier propiedad. Las variables declaradas con var son indestructibles.
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 la eliminación , la configuración nula y la configuración no definida .
Pero tenga en cuenta que comprueba el caso cuando elimina / establece la propiedad muchas veces.
Al establecer una variable en null
asegúrese de romper cualquier referencia a los objetos en todos los navegadores, incluidas las referencias circulares que se realizan entre los elementos DOM y los ámbitos de Javascript. Al usar el comando de delete
, estamos marcando los objetos que se borrarán en la próxima ejecución de la recolección de basura, pero si hay varias variables que hacen referencia al mismo objeto, eliminar una sola variable NO liberará el objeto, simplemente eliminará el vínculo entre esa variable y el objeto. Y en la próxima ejecución de la recolección de basura, solo se limpiará la variable.
Aparte de las preguntas del GC, para el rendimiento, se deben considerar las optimizaciones que el navegador puede estar realizando 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 eso puede cambiar la ''clase'' de Chrome detrás de escena.
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 objeto 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
El comando de delete
no tiene efecto en las variables regulares, solo en las propiedades. Después del comando de delete
la propiedad no tiene el valor null
, no existe en absoluto.
Si la propiedad es una referencia de objeto, el comando de eliminación elimina la propiedad pero no el objeto. El recolector de basura se hará cargo del objeto si no tiene otras referencias a él.
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).
El operador de eliminación solo elimina 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 el acceso a uno de ellos causaría un bloqueo. Hacer que todos se vuelvan nulos significaría tener más trabajo al eliminar o memoria adicional para cada objeto).
Dado que Javascript se recolecta como basura, no es necesario que elimine los objetos, ya que se eliminarán cuando ya no haya forma de consultarlos.
Puede ser útil eliminar las referencias a un objeto si ha terminado con ellos, porque esto le da al recolector de basura más información sobre lo que se puede reclamar. Si las referencias permanecen en un objeto grande, esto puede hacer que no se recupere, incluso si el resto de su programa no usa ese objeto.
Este trabajo para mí, aunque no es una buena práctica. Simplemente elimina todo el elemento asociado con el que pertenece el objeto.
for (element in homeService) {
delete homeService[element];
IE 5 a 8 tiene un error por el cual al eliminar las propiedades de un objeto host (Window, Global, DOM, etc.), el objeto TypeError "no es compatible con 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 total de significado, use el.foo !== undefined
porque "foo" in el
siempre devolverá verdadero en IE.
Si realmente necesitas la propiedad 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
Si necesita usar el objeto host con el host api ...
el.parent.removeChild(el._host);
Me topé con este artículo en mi búsqueda de esta misma respuesta. Lo que terminé haciendo es simplemente sacando obj.pop()
todos los valores / objetos almacenados en mi objeto para poder reutilizarlo. No estoy seguro si esto es una mala práctica o no. Esta técnica me resultó útil para probar mi código en las herramientas Chrome Dev o la consola web de FireFox.
Procedente de la documentación de Mozilla, "Puede utilizar el operador de eliminación para eliminar variables declaradas implícitamente pero no las declaradas con la declaración var".
Aquí está el enlace: https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Operators:Special_Operators:delete_Operator
delete
no se utiliza para eliminar un objeto en Script de Java.
delete
utilizado para eliminar una object key
en su caso
var obj = { helloText: "Hello World!" };
var foo = obj;
delete obj;
el objeto no se borra, verifique que obj todavía tome los mismos valores eliminar uso:
delete obj.helloText
y luego verifique obj, foo
, ambos son objeto vacío.