Heim > Artikel > Web-Frontend > JS-Abschlussessay
Bevor wir mit der formellen Einführung beginnen, schauen wir uns eine schwierigere Interviewfrage zu Abschlüssen an:
function fun(n,o) {
console.log(o)
return {
fun : function(m){
return fun(m,n);
}
};
}
var a = fun(0); a (2); a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun ( 1); c.fun(2); c.fun(3);
//Frage: Was sind die Ausgaben der drei Zeilen a, b und c?
(Originallink: http://www.cnblogs.com/xxcanghai/p/4991870.html)
Diese Frage ist für jeden Einzelnen schwierig, insbesondere für Anfänger, die keine solide Grundlage haben. Mir wurde schwindelig, als ich es nur ansah. Ich habe grob erklärt, was diese lustige Funktion
bewirkt (ich werde das am Ende des Artikels analysieren): Zuerst gab sie ihren zweiten Parameter aus und gab dann ein Objekt zurück, das dieses Objekt hat eine Methode fun, und dann wird diese Methode zu fun(m,n) – das Ausführungsergebnis der äußersten Funktion, Sie können es grob analysieren, aber bevor Sie über Abschlüsse sprechen, Lassen Sie uns über die Bereichskette von
js sprechen:
Jedem Teil des JS-Codes (globaler Code oder Funktion) (Achtung hier, klopfen Sie an die Tafel!!!) ist ein Bereich zugeordnet, der mit der Bereichskette verknüpft ist. Diese
-Bereichskette ist eine Objektliste oder verknüpfte Liste. Diese Gruppe von Objekten definiert die Variablen im Gültigkeitsbereich dieses Codes,
(dieser Vorgang wird als „Variablenauflösung“ bezeichnet). (variable Auflösung)‘), wird ab dem ersten Objekt in der Kette gesucht. Wenn es nicht im ersten Objekt gefunden wird, wird nach dem nächsten gesucht, und so weiter.
Im Code der obersten Ebene von js besteht die Bereichskette aus einem globalen Objekt. In einem Funktionskörper, der keine Verschachtelung enthält, gibt es zwei Objekte in der Bereichskette. Das erste ist das Objekt, in dem die Funktion
Parameter und lokale Variablen definiert, und das zweite ist das globale Objekt.
-Der Inhalt der beiden obigen Absätze stammt aus dem maßgeblichen JS-Leitfaden, dem Rhino-Buch.
Wenn eine Funktion definiert ist, behält sie tatsächlich eine Domänenkette bei. Wenn diese Funktion aufgerufen wird, erstellt sie ein neues Objekt zum Speichern ihrer lokalen Variablen, fügt
dieses Objekt der gespeicherten Bereichskette hinzu und erstellt ein neues, längeres Objekt, das den Bereich des Funktionsaufrufs darstellt. Bei verschachtelten Funktionen ist die Bereichskette bei jedem Aufruf der externen Funktion
unterschiedlich und die interne Funktion wird neu definiert. Bei jedem Aufruf der externen Funktion ist der Code der internen Funktion derselbe und
Die diesem Code zugeordnete Bereichskette ist ebenfalls unterschiedlich.
-Der obige Inhalt stammt ebenfalls aus dem maßgeblichen JS-Leitfaden, also dem Rhino-Buch.
Fasst im Allgemeinen zusammen, dass jede Funktion eine Domänenkette bildet, die Domänenkette unterschiedlich ist und der Inhalt, auf den zugegriffen werden kann, nicht Beim Zugriff auf Variablen können Sie aufgrund der
-Ordnungsbeziehung von Objekten in der Bereichskette einem Prinzip folgen – dem Proximity-Prinzip.
Nachdem wir über den Umfang gesprochen haben, sprechen wir über Schließungen.
Kurz gesagt, eine verwirrende Scope-Kette ist die Ursache für Schließungen.
Nehmen wir ein sehr einfaches Beispiel:
var d;
function otter(){
var c = 0;
console.log(c);
d = function() { c++; }
Im Allgemeinen wird bei jedem Aufruf einer js-Funktion ein neues Objekt zum Speichern lokaler Variablen erstellt und dieses Objekt zur Bereichskette hinzugefügt. Wenn die Funktion zurückkehrt, wird es aus der Bereichskette entfernt gelöscht. Wenn keine verschachtelten Funktionen und keine anderen Verweise auf dieses Bindungsobjekt vorhanden sind, wird es als Garbage Collection behandelt. Wenn verschachtelte Funktionen definiert sind, bildet jede verschachtelte Funktion eine eigene Bereichskette, und diese Bereichskette zeigt auf ein Variablenbindungsobjekt
. Wenn diese verschachtelten Funktionsobjekte in der externen Funktion gespeichert werden, werden sie ebenfalls durch Müll gesammelt die variablen Bindungsobjekte, auf die sie verweisen. Aber
Wenn diese verschachtelten Funktionen als Rückgabewerte zurückgegeben oder irgendwo in Attributen gespeichert werden, gibt es eine externe Referenz, die auf die verschachtelte Funktion verweist. Es wird nicht als
Garbage Collection behandelt, und das variable Bindungsobjekt, auf das verwiesen wird, wird nicht als Garbage Collection behandelt!
Da sich im obigen Code nach dem Aufruf von Outter die externe Variable d auf die verschachtelte Funktion bezieht, zeigt d nach Abschluss der Ausführung von Outter auf die verschachtelte Funktion
und auf das Variablenbindungsobjekt, auf das sie zeigt are Es wurde nicht recycelt, also wurde c nicht recycelt, also gibt es eine Zukunftsgeschichte. . .
Lassen Sie uns eine englische Erklärung des Abschlusses geben (das Folgende ist der Erklärung von MDN entnommen):
Ein Abschluss ist die Kombination einer Funktion und der lexikalischen Umgebung, in der diese
Funktion deklariert wurde.
Was bedeutet das? Die direkte Übersetzung des oben Gesagten lautet: Ein Abschluss ist eine Kombination aus einer Funktion und der lexikalischen Geltungsbereichsumgebung, in der die Funktion deklariert ist.
Lassen Sie uns über die eingangs erwähnte Frage sprechen:
function fun(n,o) {
console.log(o)
return {
fun:function(m) {
return fun(m,n); (1).fun(2).fun (3);
Lassen Sie mich erklären, was passiert, wenn diese Anweisung ausgeführt wird:
fun(0):
fun(0) => n = 0,o = undefiniert;
console.log(o = undefiniert;) return { fun: function(m){ return fun( m,n) } => Definieren Sie verschachtelte Funktionen, um eine Bereichskette zu bilden, und referenzieren Sie sie durch das Attribut
des zurückgegebenen Objekts fun, m = undefiniert, n =0, diese Bereichskette bleibt erhalten
fun (0).fun(1):
Tatsächlich gibt der Aufruf die fun-Methode des Objekts zurück:
function(m) =>
return fun(m,n) => m=1,n=0;
Führen Sie die Fun-Funktion erneut aus:
fun(n,o) => n=1,o=0;
console.log(o) => 0
return { fun: ...return fun(m,n) } => m = undefined,n =1; Wie oben wird die Scope-Kette gespeichert
fun(0).fun(1 ).fun(2):
Die Fun-Methode des zurückgegebenen Objekts heißt immer noch:
function(m) => m=2
return fun(m,n) m=2,n= 1
und dann fun(n,o) => n=2,o=1
aufrufenDann ist Druck O Druck 1. . .
Dann
fun(0).fun(1).fun(2).fun(3);
Immer noch heißt die Fun-Methode des zurückgegebenen Objekts:
function(m) => ; m =3
return fun(m,n) """""""" La. . .
...
Das letzte b besteht darin, die Fun-Methode aufzurufen, die das Objekt zurückgibt. Wenn fun ausgeführt wird, gibt es ein Objekt zurück, also ist b ein Objekt mit einem
-Attribut, dessen Schlüssel der Fun-Wert ist Funktion, wir nennen dieses Attribut im Allgemeinen eine Methode.
Über den letzten Punkt möchte ich tatsächlich sprechen. Wenn es notwendig ist, Fähigkeiten oder Bedingungen zur Schau zu stellen, vermeiden Sie Schließungen, wenn Sie können, denn solange Sie
Schließungen verwenden, bedeutet dies dass Ihr Programm möglicherweise nicht unbedingt Speicherplatz freigibt, wenn der Computer ausgeführt wird.
Dies hat zweifellos Auswirkungen auf die Leistung des Programms.
Das obige ist der detaillierte Inhalt vonJS-Abschlussessay. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!