2011-07-07 14 views
15
var name = function(n) { 
    var digits = ['one','two','three','four']; 
    return digits[n]; 
} 

var namenew = (function() { 
    digits = ['one','two','three','four']; 
    return function(n) { 
     return digits[n]; 
    } 
}()); 

Ambas versiones dan como resultado la misma salida, sin embargo, se dice que la segunda versión es mucho más rápida que la primera versión.Rendimiento de Javascript con cierre

Según tengo entendido, la primera versión ejecuta la función cada vez que la segunda versión almacena el resultado de la ejecución. Eso es lo que me confunde como un programador OOPS funcional/regular.

¿Cómo se puede guardar una función con su contexto interno? ¿Qué está pasando debajo del capó? ¿Puede alguien aclarar?

+1

Se trata de crear un objeto que contiene la lista de dígitos, además de un método. –

Respuesta

13

La respuesta real a esa pregunta sería de aproximadamente 3 páginas. Pero trato de hacerlo lo más corto posible. ECMA-/Javascript tiene que ver con Execution Contexts y Object. Hay tres tipos básicos de contexto en ECMAscript: Global context, Function contexts y eval contexts.

Cada vez que llame a una función, su motor la generará en su propia function context. Además, existe un llamado Activation object creado. Este objeto mística es parte de un function context que consta de al menos:

  • [cadena Alcance []]
  • activación valor de objeto
  • "este" contexto

Puede haber más propiedades en diferentes motores, pero estos tres son necesarios para cualquier implementación de ES. Sin embargo, volviendo al tema. Si se invoca un contexto de función, todos los parent contexts (o más exactamente, Activation objects de los contextos principales) se copian en la propiedad [[Scope]]. Puede considerar esta propiedad como una matriz que contiene objetos (de activación). Ahora, cualquier información relacionada con funciones se almacena en el objeto Activación (parámetros formales, variables, declaraciones de funciones).

En su ejemplo, la variable digits se almacena en el objeto de Activación para namenew. El segundo cuando se crea la función anónima interna, agrega que Activation object en sus propiedades [[Scope]].Cuando llama al digits[n] allí, Javascript primero intenta encontrar esa variable en su propio objeto de activación. Si eso falla, la búsqueda entra en Scopechain. Y listo, allí encontramos la variable porque copiamos el AO de la función externa.

Ya escribí demasiado para obtener una respuesta breve, pero para dar una buena respuesta a esa pregunta, tienes que explicar algunos conocimientos básicos sobre ES aquí. Supongo que eso es suficiente para darte una idea de lo que realmente sucede "debajo del capó" (hay mucho más por saber, si quieres leer más te daré algunas referencias).


Usted preguntó por él, se obtiene:

http://dmitrysoshnikov.com/ecmascript/javascript-the-core/

8

La primera función recrea digits cada vez que se ejecuta. Si se trata de una gran matriz, esto es innecesariamente costoso.

La segunda función almacena digits en un contexto compartido solo con namenew. Cada vez que se ejecuta namenew, solo realiza una sola operación: return digits[n].

Un ejemplo como este no mostrará ningún aumento notable en el rendimiento, pero con matrices/objetos/llamadas de funciones muy grandes, el rendimiento mejorará significativamente.

En una perspectiva de POO, el uso de un cierre de esta manera es similar al almacenamiento de datos en una variable estática.


No olvide que namenew está recibiendo el resultado de la función de cierre. El cierre en sí solo se ejecuta una vez.

+0

Desafortunadamente, entiendo todo lo que mencionaste. Lo que estoy buscando es lo que está pasando 'Under the hood' – Kiran

Cuestiones relacionadas