2010-09-20 13 views
7

Mi intuición es que es una buena idea para encapsular bloques de código en funciones anónimas como esto:¿Debo encapsular bloques de funcionalidad en funciones JavaScript anónimas?

(function() { 
    var aVar; 
    aVar.func = function() { alert('ronk'); }; 
    aVar.mem = 5; 
})(); 

Porque no voy a necesitar aVar de nuevo, así que supongo que el recolector de basura a continuación, eliminar aVar cuando sale del alcance. ¿Es esto correcto? ¿O son los intérpretes lo suficientemente inteligentes como para ver que no vuelva a utilizar la variable y limpiarla de inmediato? ¿Hay alguna razón, como el estilo o la legibilidad, que debería no usar funciones anónimas de esta manera?

Además, si nombro a la función, así:

var operations = function() { 
    var aVar; 
    aVar.func = function() { alert('ronk'); }; 
    aVar.mem = 5; 
}; 
operations(); 

qué operations entonces necesariamente se quiera dar vueltas hasta que se sale del ámbito? ¿O puede el intérprete decir inmediatamente cuándo ya no es necesario?

un mejor ejemplo

También me gustaría aclarar que no estoy hablando necesariamente de alcance mundial. Considere un bloque que se parece a

(function() { 

    var date = new Date(); // I want to keep this around indefinitely 

    // And even thought date is private, it will be accessible via this HTML node 
    // to other scripts. 
    document.getElementById('someNode').date = date; 

    // This function is private 
    function someFunction() { 
    var someFuncMember; 
    } 

    // I can still call this because I named it. someFunction remains available. 
    // It has a someFuncMember that is instantiated whenever someFunction is 
    // called, but then goes out of scope and is deleted. 
    someFunction(); 

    // This function is anonymous, and its members should go out of scope and be 
    // deleted 
    (function() { 
    var member; 
    })(); // member is immediately deleted 
    // ...and the function is also deleted, right? Because I never assigned it to a 
    // variable. So for performance, this is preferrable to the someFunction 
    // example as long as I don't need to call the code again. 

})(); 

¿Son correctas mis suposiciones y conclusiones? Cuando no voy a reutilizar un bloque, no debería encapsularlo en una función, sino encapsularlo en una función anónima para que la función no tenga referencias y se elimine después de que se invoque, ¿verdad?

+0

solo curiosidad, ¿hay una posibilidad de pérdida de memoria? – jebberwocky

Respuesta

4

Tiene razón en que las variables adheridas dentro de una función anónima son una buena práctica para evitar saturar el objeto global.

Para responder a sus dos últimas preguntas: Es completamente imposible para el intérprete saber que un objeto no se volverá a usar mientras haya una referencia globalmente visible. Para todo lo que sabe el intérprete, podría evaluar algún código que dependa de window['aVar'] o window['operation'] en cualquier momento.

Esencialmente, recordar dos cosas:

  1. Mientras un objeto es de alrededor, ninguno de sus ranuras serán liberados sin su mágicamente diga.
  2. Las variables declaradas en el contexto global son ranuras del objeto global (window en Javascript del lado del cliente).

Combinados, estos significan que los objetos en variables globales duran toda la vida de su script (a menos que la variable se reasigne). Es por eso que declaramos funciones anónimas: las variables obtienen un nuevo objeto de contexto que desaparece tan pronto como la función termina de ejecutarse. Además de la eficiencia gana, también reduce la posibilidad de colisiones de nombres.

Su segundo ejemplo (con la función anónima interna) puede ser un poco demasiado entusiasta. No me preocuparía por "ayudar al recolector de basura" allí - GC probablemente no se ejecutará en el medio de esa función de todos modos. Preocúpese por las cosas que se mantendrán persistentemente, no solo un poco más de lo que de otra manera serían. Estas funciones anónimas autoejecutables son básicamente módulos de código que, naturalmente, pertenecen juntos, por lo que una buena guía es pensar si eso describe lo que estás haciendo.

Aunque hay razones para usar funciones anónimas dentro de funciones anónimas. Por ejemplo, en este caso:

(function() { 
    var bfa = new Array(24 * 1024*1024); 
    var calculation = calculationFor(bfa); 
    $('.resultShowButton').click(function() { 
    var text = "Result is " + eval(calculation); 
    alert(text); 
    }); 
})(); 

Esto se traduce en ese gigantesco arsenal de ser capturado por el clic de devolución de llamada de modo que nunca se va. Puede evitar esto poniendo en cuarentena la matriz dentro de su propia función.

+0

Entiendo y acepto el uso de esto como medida para evitar saturar el espacio de nombres global. Creo que mi ejemplo original no demostró adecuadamente el alcance de mi pregunta. Revisé mi pregunta para incluir un mejor ejemplo. –

+0

_Lo siento por las cosas que se mantendrán persistentemente, no solo un poco más de lo que de otra manera serían._ ¡Eso es exactamente lo que estaba buscando! ¡Gracias por tu ayuda! –

1

Todo lo que agregue al alcance global permanecerá allí hasta que la página se descargue (a menos que la elimine específicamente).

En general, es una buena idea colocar variables y funciones que pertenecen juntas, ya sea en un ámbito local o en un objeto, para que añadan lo menos posible al espacio de nombres global. De esta forma, es mucho más fácil reutilizar el código, ya que puede combinar diferentes scripts en una página con riesgos mínimos para nombrar colisiones.

+0

Derecha. Estoy de acuerdo con eso. Mi pregunta es más sobre si es bueno pegar bloques individuales de código en funciones anónimas para realmente minimizar su alcance. Un ejemplo podría ser un objeto que guardo, tal vez asignándolo como miembro de un nodo HTML, pero un bloque individual dentro de él podría hacerlo y luego eliminarse. Supongo que mi pregunta es más sobre los detalles de la recolección de basura, y cuánto debo dejar que eso informe mi estilo. –

Cuestiones relacionadas