Por lo que entiendo, la gestión de memoria en JavaScript se logra mediante el recuento de referencias - mientras que una referencia a un objeto todavía existe, no se cancela la asignación. Esto significa que la creación de una pérdida de memoria en una aplicación de una sola página es trivial, y puede tropezar con las de uso provenientes de un fondo de Java. Esto no es específico de JQuery. Tome el siguiente código, por ejemplo:
function MyObject = function(){
var _this = this;
this.count = 0;
this.getAndIncrement = function(){
_this.count++;
return _this.count;
}
}
for(var i = 0; i < 10000; i++){
var obj = new MyObject();
obj.getAndIncrement();
}
Se verá normal hasta que vea el uso de la memoria. Las instancias de MyObject nunca se desasignan mientras la página está activa, debido al puntero "_this" (aumenta el valor máximo de i para verlo más dramáticamente). (En versiones anteriores de IE, nunca fueron desasignados hasta que el programa finaliza). Dado que los objetos javascript pueden compartirse entre fotogramas (no recomiendo probar esto, ya que es muy temperamental), hay casos en los que incluso en un navegador moderno JavaScript los objetos pueden permanecer mucho más tiempo de lo que deberían.
En el contexto de jQuery, las referencias A menudo se utilizan para guardar la sobrecarga de búsqueda dom - por ejemplo:
function run(){
var domObjects = $(".myClass");
domObjects.click(function(){
domObjects.addClass(".myOtherClass");
});
}
Este código se aferrará a DOMObject (y todo su contenido) para siempre, debido a la referencia a él en la función de devolución de llamada.
Si los escritores de jquery han perdido instancias como esta internamente, entonces la biblioteca en sí misma tendrá fugas, pero más a menudo es el código del cliente.
El segundo ejemplo se puede fijar en la limpieza de forma explícita el puntero cuando ya no se requiere:
function run(){
var domObjects = $(".myClass");
domObjects.click(function(){
if(domObjects){
domObjects.addClass(".myOtherClass");
domObjects = null;
}
});
}
o hacer la búsqueda de nuevo:
function run(){
$(".myClass").click(function(){
$(".myClass").addClass(".myOtherClass");
});
}
Una buena regla general es ser Tenga cuidado cuando defina sus funciones de devolución de llamada, y evite anidar demasiado cuando sea posible.
Edit: Como se ha señalado en los comentarios de Erik, también se puede usar el puntero this para evitar la unnescessary de búsqueda dom:
function run(){
$(".myClass").click(function(){
$(this).addClass(".myOtherClass");
});
}
He aquí un ejemplo: http://jsfiddle.net/qTu6y/8/ Puede usar "Hacer una foto" de Chrome en el generador de perfiles para ver que cada ejecución de ese bloque de código consume alrededor de 20 MB de RAM. (Mientras lo probaba, pulsé "Script usó demasiado RAM error en Chrome") – Raynos
+1 para "aquellos de nosotros que venimos de un fondo Java" ... y por la explicación lúcida. – Thimmayya
$ (esto) .addClass sería mejor para el rendimiento en el último caso ya que 'esto' representa una colección de elementos DOM JS central (que es lo que los objetos JQuery suelen envolver con un patrón de estilo adaptador) y JQ no tendrá que acceda nuevamente al DOM o analice cada elemento DOM en la página en el caso de