2009-10-30 19 views
5

¿Hay alguien que sepa cómo destruir una función de javascript (jquery)? Estoy usando jquery "seleccionable" y una llamada de función "editar" se activa en el evento "detener" seleccionable.destruir una función en javascript (jquery)

Dentro de esta función de "edición" he anidado funciones de interruptor con muchos eventos de "clic" y tengo muchas funciones dentro de cada evento de "clic". Mi problema es cada vez que disparo las funciones "seleccionables" y los eventos dentro de la función "editar" vuelven a sonar, pero las funciones y eventos anteriores aún existen. Lo que hago ahora es desvincular todos los eventos de la función "editar" en "inicio" seleccionable incluso.

¿Este es un problema de pérdida de memoria? y hay una forma de "destruir" las funciones en javascript? intenté declarar nula la función cuando la función finaliza pero esto no funciona. las funciones y eventos dentro de ella todavía existen.

¿alguien tiene una pista?

página de demostración aquí -> http://dreamerscorp.com/test/test01/javascript_destory_test.html

edición 2009/10/31 :) muchas gracias por su ayuda, sus comentarios son muy útiles para mí, gracias otra vez !!!

+0

+1 para la página de demostración! –

+0

Sí, otro +1 para la página de demostración. –

Respuesta

3

Básicamente lo que necesita para eliminar todas las referencias a esas funciones para que el recolector de basura de JavaScript pueda recopilarlas. Si están vinculados, debes desvincularlos. Si hay otras variables que los señalan, deben establecerse en nulo.

Podría ser útil si publicó algún código; entonces podemos dar una mejor respuesta.

... EDIT:

lo que está sucediendo aquí es, que está creando un cierre que sobrevivirá a la función que contiene:

function edit(){ 
     $('.edit').click(function(){ 
     //... 
     function _edit(boxTitle,selectedItemAmount){ 
      //... 
      $('#box .yes').click(function(){ 
      alert(boxTitle + ' for ' + selectedItemAmount + ' selected item'); 
      $('#msg').hide(); // hide msg box when yes btn is clicked 
      }); 
     } 
     //... 
     $('#box .no').click(function(){ 
      $('#msg').hide(); 
     }); 
     }); 

En otras palabras, dentro de una función, que' diciendo, "Adjunte esta función a un objeto DOM", y lo está haciendo en línea. JavaScript captura variables de contextos externos y las mantiene con vida mientras la referencia al contexto interno está activa.

Lo que hay que hacer es definir las funciones de algún lugar no en línea y luego usarlos:

function boxClickYes(e) { 
     alert(e.data.boxTitle + ' for ' + e.data.selectedItemAmount + 
     ' selected item'); 
     $('#msg').hide(); // hide msg box when yes btn is clicked 
    } 
    function boxClickNo(e) { 
     $('#msg').hide(); 
    } 
    function edit(){ 
     $('.edit').click(function(){ 
     //... 
     function _edit(boxTitle,selectedItemAmount){ 
      //... 
      $('#box .yes').bind("click", {boxTitle: boxTitle, 
      selectedItemAmount: selectedItemAmount}, boxClickYes); 
     } 
     //... 
     $('#box .no').click(boxClickNo); 
     }); 

Esto también muestra cómo utilizar la propiedad data en jQuery clic manipuladores para almacenar datos en entre el momento adjunte el controlador y la hora en que lo usa (en lugar de almacenar esos datos en un cierre que mantendrá la cadena de alcance en la memoria). El uso de funciones definidas en línea está bien cuando lo estás usando justo allí (como el cuerpo de un $.each, por ejemplo) pero no está bien cuando estás adjuntando manejadores de eventos.

+0

http://dreamerscorp.com/test/test01/javascript_destory_test.html código de ejemplo aquí :) lo que significa que tenga que desvincular cada evento dentro de la función y establecer todas las funciones en nulo? – ben

+0

gracias! esta es una muy buena demo !! ¡¡muy útil!! – ben

+0

De nada. –

7

Usted puede tratar de anular la función o anularlo asignar una función anónima que no hace nada:

myFunction = null; 
// or 
myFunction = function() {}; 

También puede hacerlo dentro de la propia función:

var autoDestroy = function() { 
    autoDestroy = null; 
    //... 
    return 1; 
}; 

autoDestroy(); // returns 1 
autoDestroy(); // TypeError: autoDestroy is not a function 
+0

¡Diseño muy inteligente! –

+0

No creo que realmente esté preguntando cómo destruir una función; más bien, él está preguntando cómo desenredar las referencias que hacen que permanezca en la memoria. –

+0

@Anthony: Sí, creo que necesitamos ver su código para dar una respuesta precisa – CMS

1

para "destruir" una función en javascript, sólo tiene que asegurarse de que la función se convierte en inalcanzable. Esto permitirá que la función sea elegible para reclamación. Una cosa a tener en cuenta es que javascript variables están obligados basado en ámbitos (no como variables individuales) y un ámbito de aplicación, con muchos objetos no utilizados, puede persistir si un enlace se mantiene al alcance:para proporcionar más ayuda requiere conocimiento del código específico y cómo se usa.

Por favor, vea el javascript borrar operador como una forma de eliminar un miembro de la variable u objeto. Establecer el valor en null/undefined/other-object se elimina en el método de alcanzar el objeto al que se hace referencia anteriormente (aunque aún podría alcanzarse de otra manera y, por lo tanto, no recuperarse), pero no elimina la variable/miembro.

delete variable 
delete obj.member 
delete obj[member] 
+0

gracias por la ayuda, he intentado el uso de "borrar" la función, pero todavía existen funciones y variables dentro de las funciones eliminados .. el siguiente es el código de ejemplo :) http://dreamerscorp.com/test/test01/ javascript_destory_test.html – ben

+0

@ben No entiendo a qué te refieres con que todavía exista en este caso. * El hecho de que la existencia pueda ser probada como positiva implica que los objetos no son elegibles para reclamo * (lo que implica que existen ...) ¿Hay alguna manera particular de que esto se pruebe? ¿Cuál es el resultado deseado? –

+0

disculpe mi poco conocimiento de javascript. lo que quiero decir con que las funciones todavía existen es porque están en un evento de "clic" y el evento "hacer clic" está en una función llamada "editar" que está bajo el evento "detener" seleccionable (pls ver código de demostración). así que cada vez que disparo seleccionable habrá una nueva tienda de controladores en la memoria. Intenté declamar la función "editar" como nula o usar el operador "eliminar" pero no funcionó. Creo que mi problema es como lo que dijo Anthony Mills. No debería usar funciones definidas en línea para adjuntar controladores de eventos.gracias por la ayuda :) – ben

6

para desenlazar los eventos en el uso de jQuery función unbind http://docs.jquery.com/Events/unbind

$("something").click(function() { 
    $("anotherOne").click(function() { 
     .... 
    }); 
}); 

en este ejemplo, cada vez que se hace clic en "algo", se añade un controlador de eventos "anotherone", por lo que si se hace clic tres veces, obtendrá tres controladores de eventos.

$("something").click(function() { 
    $("anotherOne").unbind('click').click(function() { 
     .... 
    }); 
}); 

aquí tiene la garantía de tener solo un manejador de clics en "anotherOne".

No hay necesidad de destruir controlador anterior de forma explícita.

+0

haciendo esto si tengo funciones en $ ("anotherOne"). Unbind ('click'). Click (function() {// funciones aquí}); ¿todavía existen? me refiero a que "desenlazar" simplemente elimina el evento o elimina tanto el evento como las funciones dentro del evento? – ben

+0

muchas gracias! creo que esto resolvió mis problemas :) – ben

+1

¿qué hay de usar la función "one" de jquery: $ ("algo"). one ("click", function() { $ (this) .one ("click", función() { }); }); Se ejecutará una vez para cada elemento coincidente y nunca más. http://docs.jquery.com/Events/one –

Cuestiones relacionadas