Funktionskontext ("this") in verschachtelten Funktionen

Wenn Sie eine Funktion der obersten Ebene in Javascript aufrufen, wird diediese Das Schlüsselwort in der Funktion bezieht sich auf das Standardobjekt (Fenster in einem Browser). Ich verstehe, dass es ein Sonderfall ist, die Funktion als Methode aufzurufen, da sie standardmäßig im Fenster aufgerufen wird (wie in John Resigs Buch Secrets of the JavaScript Ninja, Seite 49 erläutert). Und tatsächlich sind beide Aufrufe im folgenden Code identisch.

function func() {
  return this;
}

// invoke as a top-level function
console.log(func() === window); // true

// invoke as a method of window
console.log(window.func() === window); // true

So weit so gut ... Hier ist der Teil, den ich nicht verstehe:

Wenn eine Funktion in einer anderen Funktion verschachtelt und ohne Angabe eines aufzurufenden Objekts aufgerufen wird, wird diediese Das Schlüsselwort in der Funktion bezieht sich auch auf das Fenster. Die innere Funktion kann jedoch nicht im Fenster aufgerufen werden (siehe Code unten).

function outerFunc() {
  function innerFunc() {
    return this;
  }

  // invoke without window.* - OK
  console.log(innerFunc() === window); // true

  // invoke on window
  //window.innerFunc(); - error (window has no such method)
  console.log(window.innerFunc) // undefined
}

outerFunc();

Es macht durchaus Sinn, dass die verschachtelte Funktion im Fenster nicht verfügbar ist, da sie immerhin verschachtelt ist ... Aber dann verstehe ich nicht, warum sich das Schlüsselwort auf Fenster bezieht, als ob die Funktion im Fenster aufgerufen wurde. Was vermisse ich hier?

BEARBEITEN

Hier ist eine Zusammenfassung der großartigen Antworten und einige meiner Nachforschungen.

Es ist falsch zu sagen, dass das Aufrufen einer Funktion "normal" dasselbe ist wie das Aufrufen als Methode vonFenster. Dies ist nur richtig, wenn die Funktion global definiert ist.

Der Funktionskontext (der Wert vondiese Schlüsselwort) hängt nicht davon ab, wo / wie die Funktion definiert ist, sondern davon, wie sie aufgerufen wird.

Unter der Annahme, dass der Code nicht im strikten Modus ausgeführt wird, wird beim Aufrufen einer Funktion "normal" der Funktionskontext auf window festgelegt (beim Ausführen in einem Browser oder dem entsprechenden globalen Objekt in anderen Umgebungen).

Eine Ausnahme zu den oben genannten Regeln ist die Verwendung vonbinden eine Funktion erstellen. In diesem Fall kann die Funktion, auch wenn sie "normal" aufgerufen wird, einen anderen Kontext als habenFenster. Das heißt, in diesem Fall wird der Kontext dadurch bestimmt, wie Sie die Funktion erstellen, anstatt wie Sie sie aufrufen. Obwohl dies streng genommen nicht korrekt ist, weilbinden Erstellt eine neue Funktion, die die angegebene Funktion intern mit aufruftsich bewerben. Der Kontext dieser neuen Funktion wird weiterhin durch den Aufruf bestimmt, aber er schützt den Kontext der Funktion, die er intern mithilfe von aufruftsich bewerben.

Wenn ich "normal" aufrufe, verweise ich auf die folgende einfache Art des Aufrufs:

myFunction();

Um das Bild zu vervollständigen, finden Sie hier eine kurze Beschreibung anderer Aufrufmethoden und des entsprechenden Kontexts:

Als Eigenschaft eines Objekts (Methode) ist der Kontext das Objekt

Mit apply oder call wird der Kontext explizit angegeben

Mit demNeu Operator (als Konstruktor) - Der Kontext ist ein neu erstelltes Objekt

Fühlen Sie sich frei, die oben genannten Informationen bei Bedarf zu aktualisieren, zum Nutzen von Personen mit ähnlichen Fragen. Vielen Dank!

Antworten auf die Frage(5)

Ihre Antwort auf die Frage