Ho pensato di avere una comprensione ragionevole dell'oggetto this
in JavaScript. Quando ho a che fare con oggetti, callback, ed eventi e gestori, non ho avuto problemi da tempo immemorabile. Ora, tuttavia, tutto è cambiato.Chiusura JavaScript e questo oggetto
Mi sono innamorato perdutamente di JavaScript. Pure JS, cioè non jQuery, prototype.js, dojo ... Quindi, naturalmente, ho iniziato a utilizzare le chiusure. In alcuni casi, però, lo this
mi sta prendendo alla sprovvista. Prendete questo frammento per una:
function anyFunc(par)
{
//console.log(par);
console.log(this);
}
function makeClosure(func)
{
return function(par)
{
return func(par);
}
}
var close = makeClosure(anyFunc);
close('Foo');
var objWithClosure = {cls:makeClosure(anyFunc),prop:'foobar'};
objWithClosure.cls(objWithClosure.prop);
var scndObj = {prop:'Foobar2'};
scndObj.cls = makeClosure;
scndObj.cls = scndObj.cls(anyFunc);
scndObj.cls(scndObj.prop);
In tutti e tre i casi, i registri this
come l'oggetto finestra. Si tratta di una soluzione semplice, naturalmente: opere
function makeClosure(func)
{
return function(par)
{
return func.call(this,par);
}
}
questa correzione, l'ho messo qui per evitare le persone che rispondono presente, senza spiegare che cosa ho bisogno di sapere: perché questo comporta il modo in cui lo fa qui?
assicura che il chiamante sia effettivamente l'oggetto a cui appartiene la chiusura. Quello che non riesco a capire è questo: Abbastanza sicuro, this
punti per l'oggetto finestra nel primo caso, ma in altri casi, non dovrebbe. Ho provato a registrare this
nella funzione makeClosure appena prima di tornare, e ha registrato l'oggetto stesso, non l'oggetto window
. Ma quando viene utilizzata la chiusura effettiva, this
torna a puntare all'oggetto finestra. Perché?
L'unica cosa che posso pensare è che, passando la funzione anyFunc
come argomento, sto effettivamente passando window.anyFunc
. Così ho provato questa soluzione rapida:
function makeClosure(func)
{
var theFunc = func;
return function(par)
{
theFunc(par);
}
}
con i risultati attesi, this
punti ora agli oggetti, ma ancora una volta: perché? Ho qualche idea (theFunc
è un riferimento alla funzione nell'ambito locale [this > private: theFunc
]?), Ma sono sicuro che ci sono persone qui con molto più know-how quando si tratta di JS, quindi speravo di ottenere qualche spiegazione o link ad articoli pena di leggere da loro ...
Grazie
Aggiornamento
Here's a fiddle, può essere ho lasciato fuori qualcosa, ma qui questo registra ogni sorta di cose;)
E dit/Update 2
The case that confuses me è qui.
Modifica finale
Ok, questo è sempre un messaggio piuttosto disordinato. Quindi, per chiarire: quello che mi aspettavo era un comportamento simile a questo:
function makeClosure()
{
function fromThisFunc()
{
console.log(this);
}
return fromThisFunc;
}
var windowContext = makeClosure();
windowContext();
var objectContext = {cls:makeClosure()};
objectContext.cls();
Quello che mi ha colto, era che la funzione anyFunc
non è stato dichiarato nell'ambito di applicazione corretta e, quindi, this
indicò l'oggetto finestra. Ho trovato questo fuori leggendo un ancient scroll che ho trovato da qualche parte sul web.
Ma qualcosa un po 'più complicato è accaduto perché l'oggetto funzione ora denominato da globalVar stato creato con un [[scope]] immobili riferibile ad una catena portata contenente la/oggetto variabile attivazione appartenente al contesto di esecuzione in che è stato creato (e l'oggetto globale). Ora l'oggetto Activation/Variable non può essere garbage collector poiché l'esecuzione dell'oggetto function a cui fa riferimento globalVar dovrà aggiungere l'intera catena dell'ambito dalla sua proprietà [[scope]] all'ambito del contesto di esecuzione creato per ogni chiamata a esso.
Quindi quello che dovevo fare, è stato semplificare piuttosto che complicare le cose:
function fromThisFunc()
{
console.log(this);
}
function makeClosure(funcRef)
{
//some code here
return funcRef;
}
che dovrebbe funzionare, giusto?
PS: I'll tranne la risposta di Alnitak, ma un ringraziamento speciale va a Felix Kling per tutta la pazienza e informazioni.
non si è davvero ottenere ciò che altra risposta che un link ad una spiegazione globale di chiusure potrebbe essere fatto. Questo corso è una lettura eccellente e dovrebbe rimuovere tutte le incertezze: http://ejohn.org/apps/learn/ –
Il problema non è che non ottengo chiusure. Quello che sta causando il mal di testa è che non sono del tutto sicuro di cosa succede all'oggetto "questo" quando faccio le chiusure come faccio io qui –
Non riesco a riprodurre il ricordo che descrivi. Ottengo 'DOMWindow',' Object', 'Object': http://jsfiddle.net/GErkX/, mentre la tua seconda" correzione "mi dà 3 x' DOMWindow': http://jsfiddle.net/tZXQF/ –