2011-12-29 18 views
18

Qualcuno può spiegarmi perché A è vero e B è falso? Mi sarei aspettato che anche B fosse vero.questo valore in JavaScript funzione anonima

function MyObject() { 

}; 

MyObject.prototype.test = function() { 
    console.log("A", this instanceof MyObject); 
    (function() { 
     console.log("B", this instanceof MyObject); 
    }()); 
} 

new MyObject().test(); 
+5

Benvenuti in ambito funzionale in JavaScript. – zzzzBov

+1

@zzzzBov: Questa non è una chiusura. – SLaks

+0

Potrebbe essere utile utilizzare un'ulteriore coppia di paren per migliorare la leggibilità: '(new MyObject()) .test()' –

risposta

15

this è speciale.Fa riferimento all'oggetto per cui la funzione viene chiamata per conto di (più comunemente tramite la sintassi del punto).

Quindi, nel caso di A, la funzione viene richiamata per conto di un nuovo oggetto MyObject. B si trova in una funzione diversa che non viene chiamata esplicitamente per conto di alcun oggetto, pertanto this imposta automaticamente l'oggetto globale (window).

In altre parole, this cambia a seconda di come la funzione è chiamata, non dove o come è definita. Il fatto che si stia utilizzando una funzione anonima (definita all'interno di un'altra funzione) è casuale e non ha alcun effetto sul valore di this.

+4

La tua istruzione" 'this' cambia a seconda di come la funzione è * chiamata *, non dove o come è definito ", può essere fuorviante.Infatti, 'this' è semplicemente il proprietario della funzione chiamata - e di per sé è sempre o esplicitamente definito o predefinito per l'oggetto globale. 'myVar.doSomething = doSomething;' definisce la funzione 'myVar.doSomething' come' doSomething' dove 'this' farà sempre riferimento a' myVar' quando chiama 'myVar.doSomething()', indipendentemente da dove 'myVar.doSomething() 'è chiamato da. La tua affermazione potrebbe suggerire diversamente. – Navigateur

3

this è impostato in base a come si chiama la funzione.
La funzione anonima è una normale chiamata di funzione, quindi this è l'oggetto globale.

È possibile scrivere (function() { ... }).call(this) per chiamarlo esplicitamente con il numero this.

+0

Beh, sto assumendo la modalità rigorosa, quindi ... ':' –

+0

@ ŠimeVidas: Cosa? – SLaks

+0

... quindi 'questo' è 'indefinito'. –

26

All'interno della funzione anonima this è l'oggetto globale.

All'interno di test, questa è l'istanza di MyObject su cui è stato richiamato il metodo.


Ogni volta che si chiama una funzione come questa:

somceFunction(); // called function invocation 

this è sempre l'oggetto globale, o undefined in modalità rigorosa (a meno che non someFunction è stato creato con bind** - vedi sotto)

Ogni volta che si chiama una funzione come questa

foo.someMethod(); //called method invocation 

this è impostato su foo


** EcmaScript5 definisce una funzione bind che ti permette di creare una funzione che ha un valore pre-impostato per this

Quindi questo

var obj = { a: 12 }; 
    var someFunction = (function() { alert(this.a); }).bind(obj); 
    someFunction(); 

Le cause someFucntion ad essere invocate con this pari a obj e avvisi 12. Ho portare questo solo per notare che questo è un potenziale eccezione alla regola che ho citato sulle funzioni invocate come

someFunction(); 

avere sempre this pari a l'oggetto globale (o undefined in modalità rigorosa)

+0

La riga '(function() {alert (this.a);}). Bind (obj)' è esattamente ciò che stavo cercando: contesto vincolante per una funzione anonima. Funziona perfettamente, +1 –

+0

puoi anche impostare 'this' usando' func.call (this, arg1, arg2 ..) ' – Omu

6

Nella funzione anonima, this è associato all'oggetto globale (window in un ambiente browser).

ci sono vari modi di accesso dell'istanza:

var self = this; 
(function() { 
    console.log("B", self instanceof MyObject); 
}()); 

o

(function() { 
    console.log("B", this instanceof MyObject); 
}).call(this); 
Problemi correlati