2012-01-04 22 views
8

Soy nuevo en JavaScript, y estoy teniendo problemas para entender este código:malentendido de JavaScript cierres

function addProperty(o) { 
    var value; 

    o["get"] = function() { return value; } 
    o["set"] = function(v) { value = v; } 
} 

var a = {}; 
addProperty(a); 
var b = {}; 
addProperty(b); 

a.set(4); 
b.set(5); 
print("a is " + a.get() + "; b is " + b.get()); 

Esta impresora (en v8/d8) a is 4; b is 5. Si hago un comentario sobre la línea var value;, obtengo a is 5; b is 5. ¿Dónde está el objeto 'valor' y por qué hay dos? Gracias.

+0

No entiendo "¿por qué? allí dos de ellos "parte de la pregunta. ¿Podrías aclararlo por favor? – slinzerthegod

+0

El objeto 'a' tiene un valor asociado, que contiene el número entero '4', y el objeto 'b' tiene un valor asociado, que contiene el número entero '5'. – EML

Respuesta

12

La variable value es del fabricante addProperty. La primera vez que se llama a addProperty, se crea un nuevo value, sobre el que se cierran las dos funciones. La segunda vez que se llama addProperty, se crea un segundo value sobre el que se cierran dos funciones nuevas.

Extracción var crea una mundialvaluewindow en el objeto que es compartida por todas las funciones.

Tal vez quiere decir que hacer esto:

function createPropertyMgr() { 
    var value; 
    return function(o) { 
     o["get"] = function() { return value; } 
     o["set"] = function(v) { value = v; } 
    } 
} 

var addProperty = createPropertyMgr(); 

Esta nueva función addProperty se cierra sobre una value no importa cuántas veces se llama. No estoy seguro de entender el caso de uso, pero eso debería demostrar la diferencia.

+4

+1 Hay un 'valor' en * fuente *, pero dos en * memoria *. Esta parece ser la confusión del OP. – pimvdb

+0

Por lo tanto, crea una copia del valor var en cada llamada addProperty. Pero, ¿cómo se une al argumento objeto? –

+1

@TomasNarros: de la misma manera. Los parámetros formales, las declaraciones de funciones y las variables declaradas con 'var' son todos parte del 'Objeto de Activación', es decir, que se copian para crear un cierre léxico. – jAndy

1

Cuando no declara explícitamente una variable dentro de una función, su alcance se asume como global. es decir, en su segundo caso, dado que no ha declarado value explícitamente como local a la función addProperty(), se trata como global.

Pero cuando lo declaras explícitamente dentro de una función, se convierte en local para la función. Cada vez que se invoca la función, se crea una nueva copia de la variable local de la función en la pila (y lo que es más importante, se queda en la pila siempre que haya una referencia)