2017-02-22 4 views
1

Nachdem die Grundlagen der Verschlüsse zu verstehen gibt es einen Zweifel daran, dass ich noch eindringlichen:Wo befindet sich die umschließende Funktion nach der Ausführung oder nach der Rückgabe der Closure-Funktion?

Wo umschließenden Funktion seine Ausführung Post wohnt oder nach dem Schließen-Funktion zurückkehrt?

Ich glaube, Funktionen befinden sich in Stack-Datenstruktur und von der Spitze des Stapels abgehängt, sobald Funktion die Ausführung beendet/gibt einen beliebigen Wert zurück.

Aber in Closures, werden innere Funktion in den Zustand zugreifen müssen noch Funktion der Einhausung, wie?

function sayHello(name) { 
    var text = name + ' !!!'; // Local variable 
    return function(wish) { console.log(wish + ', ' +text); } 
} 

var say = sayHello('Bob'); 

say('Hey'); 
say('Hello'); 

Wo ist sayHello vorhanden, wenn es eine Funktion gibt, als von der Funktion Stapelrahmen entfernt?

+2

* „Aber in Closures, wird innere Funktion noch auf den Zustand zugreifen muß, um in Abhängigkeit von Enclosing, wie?“ * Das ist eine Implementierung Detail und verschiedene Motoren könnten dies anders machen, sondern auch die Umwelt (die hält die Bindungen) wahrscheinlich auf dem Heap gespeichert. –

+0

@FelixKling danke für deine Antwort. Ich habe noch einige Fragen wie: Wo befinden sich Funktionen und Objekte in Javascript? Finde keine Hilfe online. Verfügen Sie über Ressourcen, die mehr Licht auf Speicherzuweisung und -verwaltung in JS werfen? – BeingSuman

Antwort

1

Dies ist ein sehr guter Artikel zu diesem Thema.

https://dmitryfrank.com/articles/js_closures

Scope Kette

Wenn ein JavaScript-Code ausgeführt wird, muss es irgendwo seine lokalen Variablen zu speichern. Nennen wir diesen Ort als Scope-Objekt (manche bezeichnen ihn als LexicalEnvironment). Wenn Sie z. B. eine Funktion aufrufen und die Funktion lokale Variablen definiert, werden diese Variablen im Bereichsobjekt gespeichert. Sie können es sich als normales JavaScript-Objekt vorstellen, mit dem bemerkenswerten Unterschied, dass Sie nicht direkt auf das gesamte Objekt verweisen können. Sie können nur seine Eigenschaften ändern, aber Sie können nicht auf das Bereichsobjekt selbst verweisen.

Dieses Konzept des Bereichsobjekt ist sehr verschieden von, sagen wir, C oder C++, wo lokale Variablen auf dem Stapel abgelegt werden. In JavaScript werden Bereichsobjekte stattdessen im Heapspeicher zugewiesen (oder verhalten sich zumindest so), sodass sie möglicherweise zugewiesen bleiben, selbst wenn die Funktion bereits zurückgegeben wurde. Mehr dazu später.

Wie Sie vielleicht erwarten, Umfang Objekt könnte Elternteil haben. Wenn der Code versucht, auf eine Variable zuzugreifen, sucht Interpreter nach der Eigenschaft des aktuellen Bereichsobjekts. Wenn die Eigenschaft nicht vorhanden ist, wird der Interpreter zum übergeordneten Bereichsobjekt verschoben und dort gesucht. Und so weiter, bis der Wert gefunden ist, oder es gibt keine Eltern mehr. Nennen wir diese Sequenz von Scope-Objekten als Scope-Kette. Das Verhalten beim Auflösen einer Variablen in der Gültigkeitsbereichskette ist dem Verhalten der prototypischen Vererbung sehr ähnlich, wobei wiederum ein bemerkenswerter Unterschied besteht: wenn Sie versuchen, auf eine nicht vorhandene Eigenschaft des regulären Objekts zuzugreifen, und die Prototypkette nicht enthält diese Eigenschaft entweder, es ist kein Fehler: undefined wird automatisch zurückgegeben. Wenn Sie jedoch versuchen, auf nicht vorhandene Eigenschaft in der Bereichskette zuzugreifen (d. H. Auf eine nicht vorhandene Variable zuzugreifen), tritt ReferenceError auf.

Verwandte Themen