2011-07-02 12 views
5

Este código da como resultado "!" que se registra en la consola.detalles de cierres en JavaScript y funciones anónimas

var g = {}; 
(function() { 
    var t = this; 
    t.x = "x"; 
    g.a = function() { 
     console.log(t.x); 
    }; 
})(); 

(function() { 
    var t = this; 
    t.x = "!"; 
    g.b = function() { 
     console.log(t.x); 
    }; 
})(); 

g.a(); 

hacer funciones anónimas comparten un this? ¿Estoy usando this mal? Realmente no entiendo lo que está pasando aquí.

Me gustaría g.a() para continuar devolviendo el valor de x definido en la primera función anónima.

Estoy usando node.js si hace la diferencia.

Respuesta

4

En las funciones inmediatas, this se refiere a global object[docs]. Entonces, en este caso, en ambas funciones, this se refiere al mismo elemento y está sobrescribiendo x con la segunda llamada.

A qué objeto se refiere this por cómo se llama a la función.

  • Si sólo ejecuta una función con funcName();, a continuación, se refiere a la this objeto global.
  • Si la función está asignada a una propiedad de un objeto, obj.funcName(), this se refiere al objeto.
  • Si llama a la función con el operador new, new funcName();, this se refiere a un objeto vacío que hereda del prototipo de funciones.

También puede establecer explícitamente this mediante el uso de call[docs] o apply[docs].


En vez refiriéndose a this, se podría crear un nuevo objeto en ambas funciones:

var t = {}; 

Nota adicional: no hace ninguna diferencia si se ejecuta el código en el navegador o con node.js. El objeto global es parte de la especificación y debe ser provisto por el entorno de ejecución. En los navegadores es el objeto window, no sé qué es en node.js, pero no importa, siempre que siga la especificación.

+0

¿No 'esto' se refiere a la función a veces? –

+3

@luxun: ¿Te refieres a la función en sí? No nunca. –

+3

Bueno, nunca, a menos que configures las cosas específicamente para que así sea, pero eso sería raro. Ciertamente no lo hace por defecto ni nada. – Pointy

3

Felix Kling es la respuesta correcta larga. Pero quería meter su cuchara con lo que creo que realmente quiere:

var g = {}; 
(function() { 
    var x = "x"; 
    g.a = function() { 
     console.log(x); 
    }; 
})(); 

(function() { 
    var x = "!"; 
    g.b = function() { 
     console.log(x); 
    }; 
})(); 

g.a(); // "x" 
g.b(); // "!" 

Ahora g.a() y g.b() tanto impresión x, pero cada función tiene su propia separada x compartido con el cierre. Si estas variables deben ser privadas y solo se puede acceder internamente a cada una de estas funciones, esta es la forma en que las ocultas y persiste a través de múltiples llamadas.

1

Cuando miro esta secuencia de comandos en el depurador en Chrome como lo ha mostrado, el valor "this" en ambas funciones anónimas se establece en la variable global "ventana".Esto significa que cada función anónima está configurando el valor de window.x, por lo que la última ejecución es la que sobrevive, es decir window.x == "!" después de que se ejecuta la segunda función anónima.

No me queda claro qué esperaba que fuera "esto" o qué es lo que realmente está tratando de lograr con este código, así que no sé qué alternativa sugerir. Si solo quiere que el estado anterior en la función anónima sobreviva para la función interna, entonces puede simplemente confiar en las variables locales (que sobrevivirán en el cierre) y no usar la referencia "this" en absoluto. El ejemplo de Squeegy muestra eso.

Cuestiones relacionadas