JavaScript-Schließung und das dieses Objekt

Ich dachte, ich hätte ein vernünftiges Verständnis für diethis Objekt in JavaScript. Ich hatte seit jeher kein Problem damit, wenn ich mit Objekten, Rückrufen, Ereignissen und Handlern zu tun hatte. Jetzt hat sich jedoch alles geändert.

Ich habe mich Hals über Kopf in JavaScript verliebt. Pure JS, also nicht jQuery, prototype.js, dojo ... Also habe ich mich natürlich für Verschlüsse entschieden. In einigen Fällen jedochthis erwischt mich hier unvorbereitet. Nehmen Sie diesen Ausschnitt für einen:

<code>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);
</code>

In allen drei Fällenthis protokolliert als Fensterobjekt. Es ist natürlich eine einfache Lösung:

<code>function makeClosure(func)
{
    return function(par)
    {
        return func.call(this,par);
    }
}
</code>

Dieses Update funktioniert, ich habe es hier platziert, um zu vermeiden, dass Leute darauf antworten, ohne zu erklären, was ich wissen muss: Warum verhält es sich hier so?

stellt sicher, dass der Anrufer effektiv das Objekt ist, zu dem der Verschluss gehört. Was ich nicht verstehe, ist Folgendes:this zeigt im ersten Fall auf das Fensterobjekt, in anderen Fällen sollte dies jedoch nicht der Fall sein. Ich habe versucht, mich anzumeldenthis in der makeClosure-Funktion kurz vor der Rückkehr, und es hat das Objekt selbst protokolliert, nicht diewindow Objekt. Aber wenn der eigentliche Verschluss verwendet wird,this ist zurück auf das Fensterobjekt zu zeigen. Warum?

Das Einzige, woran ich denken kann, ist, dass ich dieanyFunc fungiere als argument, ich komme eigentlich vorbeiwindow.anyFunc. Also habe ich diese schnelle Lösung ausprobiert:

<code>function makeClosure(func)
{
    var theFunc = func;
    return function(par)
    {
        theFunc(par);
    }
}
</code>

Mit den erwarteten Ergebnissen,this zeigt nun auf die objekte, aber nochmal: warum? Ich habe ein paar Ideen (theFunc ist ein Verweis auf die Funktion im lokalen Bereich [this > private: theFunc]?), aber ich bin mir sicher, dass es hier Leute gibt, die viel mehr Know-how in Bezug auf JS haben. Ich hatte also die Hoffnung, mehr Erklärungen oder Links zu Artikeln zu erhalten, die es wert sind, von ihnen gelesen zu werden ...

Vielen Dank

Aktualisieren

Hier ist eine Geige, vielleicht habe ich etwas ausgelassen, aber hier werden alle möglichen Dinge protokolliert;)

Bearbeiten / Aktualisieren 2

Der Fall, der mich verwirrt ist hier.

Final Edit

Ok, das wird ein ziemlich chaotischer Beitrag. Zur Verdeutlichung: Was ich erwartet hatte, war ein ähnliches Verhalten:

<code>function makeClosure()
{
    function fromThisFunc()
    {
        console.log(this);
    }
    return fromThisFunc;
}

var windowContext = makeClosure();
windowContext();
var objectContext = {cls:makeClosure()};
objectContext.cls();
</code>

Was mich gefangen hat, war die FunktionanyFunc wurde nicht im richtigen Umfang deklariert, und daherthis zeigte auf das Fensterobjekt. Ich fand das heraus, indem ich ein Buch lasantike Schriftrolle Ich habe irgendwo im Web gefunden.

Es ist jedoch etwas komplizierter geworden, weil das Funktionsobjekt, auf das globalVar jetzt verweist, mit einer [[scope]] -Eigenschaft erstellt wurde, die auf eine Scope-Kette verweist, die das Activation / Variable-Objekt enthält, das zu dem Ausführungskontext gehört, in dem es erstellt wurde (und das globale Objekt). Jetzt kann das Activation / Variable-Objekt auch nicht mit Garbage-Collection bearbeitet werden, da die Ausführung des Funktionsobjekts, auf das globalVar verweist, die gesamte Gültigkeitskette von seiner [[scope]] -Eigenschaft zum Gültigkeitsbereich des Ausführungskontexts hinzufügen muss, der für jeden Aufruf von erstellt wird es.

Also musste ich die Dinge vereinfachen und nicht komplizieren:

<code>function fromThisFunc()
{
    console.log(this);
}

function makeClosure(funcRef)
{
    //some code here
    return funcRef;
}
</code>

Das sollte doch klappen, oder?

PS: Ich werde Alnitaks Antwort nicht akzeptieren, aber ein besonderer Dank geht an Felix Kling für all die Geduld und die Informationen.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage