2012-03-22 13 views
67

¿Por qué esta en una función anónima indefinida cuando se usa javascript en modo estricto? Entiendo por qué esto podría tener sentido, pero no pude encontrar ninguna respuesta concreta.¿Por qué es "esto" en una función anónima indefinida cuando se usa strict?

Ejemplo:

(function() { 
    "use strict"; 

    this.foo = "bar"; // *this* is undefined, why? 
}()); 

prueba en un violín: http://jsfiddle.net/Pyr5g/1/ Salida del registrador (Firebug).

+3

Tenga en cuenta que esto no tiene nada que ver con las funciones anónimas, sino con el método de invocación. Vea [este violín modificado] (http://jsfiddle.net/Pyr5g/3/) (busque en el registro de la consola). – Phrogz

+0

@Phrogz: es posible que de aquí provenga la confusión. Gracias por señalar eso. –

Respuesta

79

Es porque, hasta ECMAscript 262 edición 5, hubo una gran confusión si las personas que usaban el constructor pattern, olvidaron usar la palabra clave new. Si olvidó usar new al llamar a una función de constructor en ES3, this hizo referencia al objeto global (window en un navegador) y le pegaría al objeto global con variables.

Eso fue un comportamiento terrible y la gente en ECMA decidió, simplemente establecer this en undefined.

Ejemplo:

function myConstructor() { 
    this.a = 'foo'; 
    this.b = 'bar'; 
} 

myInstance  = new myConstructor(); // all cool, all fine. a and b were created in a new local object 
myBadInstance = myConstructor(); // oh my gosh, we just created a, and b on the window object 

La última línea se generará un error en la ES5 estricta

"TypeError: this is undefined" 

(que es un comportamiento mucho mejor)

+4

Esto tiene sentido. ¿Tiene una referencia para respaldar la declaración? –

+1

@RobW: Tendría que buscarme a mí mismo, pero escuché a Douglas Crockford varias veces donde dijo, este fue el motivo de esa decisión. – jAndy

+1

Se menciona en JavaScript: The Good Parts por Crockford. Se describe en detalle. Sin embargo, no sobre la decisión de ECMA. – madr

12

Hay un mecanismo llamado "boxeo" que envuelve o cambia el objeto this antes de ingresar al contexto de la función llamada. En su caso, el valor de this debe ser undefined porque no está llamando a la función como método de un objeto. Si no es estricto modo, en este caso, esto es reemplazado por el objeto window. En el modo strict, siempre se mantiene sin cambios, por eso es undefined aquí.

Usted puede encontrar más información en
https://developer.mozilla.org/en/JavaScript/Strict_mode

+0

Gracias. Lamentablemente, no puedo marcar dos respuestas como correctas. –

+0

@samuel entonces, ¿cómo podemos asignar una variable al objeto ventana en modo estricto? –

5

Según This Stack Overflow answer, puede utilizar this dentro de funciones anónimas, mediante una llamada telefónica .call(this) al final de la misma.

(function() { 
    "use strict"; 

    this.foo = "bar"; 
}).call(this); 
+0

Tenga en cuenta que 'this' será el objeto' Ventana' en este caso, que puede no ser deseado – Ninjakannon

Cuestiones relacionadas