2012-03-22 9 views
67

Perché questo in una funzione anonima non definita quando si utilizza javascript in modalità rigorosa? Capisco perché questo abbia senso, ma non sono riuscito a trovare alcuna risposta concreta.Perché "questo" in una funzione anonima non è definito quando si utilizza strict?

Esempio:

(function() { 
    "use strict"; 

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

di prova in un violino: http://jsfiddle.net/Pyr5g/1/ Scopri i logger (Firebug).

+3

Si noti che questo non ha nulla a che fare con le funzioni anonime, ma il metodo di chiamata. Vedi [questo violino modificato] (http://jsfiddle.net/Pyr5g/3/) (guarda nel log della console). – Phrogz

+0

@Phrogz: questo potrebbe essere il motivo di confusione. Grazie per la segnalazione. –

risposta

79

È perché, fino all'edizione ECMAscript 262 5, si è verificata una grande confusione se le persone che utilizzano constructor pattern, hanno dimenticato di utilizzare la parola chiave new. Se si è dimenticato di utilizzare new quando si chiama una funzione di costruzione in ES3, this fa riferimento all'oggetto globale (window in un browser) e si clobber l'oggetto globale con le variabili.

Questo era un comportamento terribile e così le persone dell'ECMA hanno deciso, solo per impostare this su undefined.

Esempio:

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 

L'ultima riga avrebbe gettato un errore nel ES5 rigorosa

"TypeError: this is undefined" 

(che è un comportamento molto meglio)

+4

Questo ha senso. Hai un riferimento per eseguire il backup della dichiarazione? –

+1

@RobW: avrei dovuto cercare me stesso, ma ho sentito diverse volte Douglas Crockford, dove ha detto, questo era il motivo di quella decisione. – jAndy

+1

Viene citato in JavaScript: The Good Parts di Crockford. È descritto in dettaglio. Non riguardo alla decisione dell'ECMA, comunque. – madr

12

C'è un meccanismo chiamato "boxe" che avvolge o modifica l'oggetto this prima di accedere al contesto della funzione chiamata. Nel tuo caso, il valore di this dovrebbe essere undefined perché non stai chiamando la funzione come metodo di un oggetto. In modalità non rigida, in questo caso, questo viene sostituito dall'oggetto window. Nella modalità strict è sempre invariato, ecco perché è undefined qui.

è possibile trovare ulteriori informazioni a
https://developer.mozilla.org/en/JavaScript/Strict_mode

+0

Grazie. Purtroppo non posso contrassegnare due risposte come corrette. –

+0

@samuel quindi come possiamo assegnare una variabile all'oggetto della finestra in modalità rigorosa ?? –

5

Secondo This Stack Overflow answer, è possibile utilizzare this all'interno funzioni anonime, semplicemente chiamando .call(this) alla fine di esso.

(function() { 
    "use strict"; 

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

Si noti che 'this' sarà l'oggetto' Window' in questo caso, che potrebbe non essere desiderato – Ninjakannon

Problemi correlati