confusión sobre la recolección de basura entre los cierres
Frecuentes
Visto 75 veces
2
No he estado seguro acerca de las reglas de la recolección de basura JS en torno a un cierre por un tiempo, así que creo que también podría preguntar ... Aquí hay un buen ejemplo que tengo curiosidad sobre la participación de jQuery $.each
método:
storeSelection: function() {
var enabledIds = {};
$.each(this.nodes, function(index, node) {
if (node.enabled) {
enabledIds[ node.id ] = true;
}
});
this.selection = enabledIds;
}
El fragmento anterior es, por supuesto, parte de un objeto literal. Entonces, creé un nuevo objeto en la parte superior de la función externa que almacenará las ID de los elementos habilitados dentro de una matriz. Usando jQuery .each()
método, estoy recorriendo la matriz de elementos y registrando ID habilitados. Finalmente, guardo la selección como miembro del objeto principal.
Mi pregunta involucra esa función interna que hace referencia a la enabledIds
objeto del alcance externo. Ya que enabledIds
se quedará, ¿eso impide que se recopile la función interna? Supongo que no, porque es solo una variable que se borra al final de la función interna, ¿verdad? Para convertirse en una fuga, asumo que la función interna necesitaría hacer una referencia directa al objeto externo, como en:
$.each(this.nodes, function(index, node) {
this.badIdea = enabledIds;
if (node.enabled) {
enabledIds[ node.id ] = true;
}
});
Sin embargo... Siempre estoy confuso con esta regla. ¡Cualquier ayuda para aclarar esta confusión sería apreciada!
2 Respuestas
3
No, incluso su segundo ejemplo no sería suficiente para causar una fuga. badIdea
se adjunta a los nodos individuales, y el $.each
el bloque saldría y se recolectaría como basura. Todos los navegadores modernos utilizan un algoritmo de "marcar y barrer" para la recolección de elementos no utilizados de javascript, que sigue las asociaciones padre a hijo y recopila cualquier "inalcanzable", es decir, cualquier cosa a la que no se pueda acceder mediante uno de estos árboles.
contestado el 22 de mayo de 12 a las 18:05
1
Tienes razón, las variables de la función interna (index
, node
) se recolectarán como basura, porque ya no se puede acceder a ellos.
En este ejemplo, ¿puede acceder bigstr
?
a = function() {
var bigstr = new Array(1000000).join('x');
return function() { return bigstr; };
}();
Sí tu puedes: a()
, por lo que no se recopila. ¿Qué pasa con este ejemplo:
a = function() {
var bigstr = new Array(1000000).join('x');
return function(n) { return eval(n); };
}();
De nuevo, puedes: a('bigstr')
.
Pero que tal este:
a = function() {
var smallstr = 'x';
var bigstr = new Array(1000000).join('x');
return function(n) { return smallstr; };
}();
Ya no puede acceder a él y es un candidato para la recolección de elementos no utilizados.
contestado el 22 de mayo de 12 a las 18:05
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas javascript jquery closures or haz tu propia pregunta.