2017-10-24 5 views
0

ich über Schließungen auf MDN lese und ich kann nicht etwas in den folgenden Code verstehen:Closures - Variable ändern Nach dem Gebrauch

var test = 1; 

function makeFunc() { 
    var name = 'Mozilla'; 
    function displayName() { 
    alert(name + ' ' + test); 
    } 
    return displayName; 
} 

//Create myFunction - test should still be set to 1 at this point 
var myFunc = makeFunc(); 

test = 99999; 

myFunc(); 

Warum ist Mozilla 99999 statt Mozilla 1 gedruckt werden, wenn die Funktion während test erstellt wurde wurde zugewiesen 1? Sollten Primitive nach Werttypen nicht? Ich glaube auch nicht, dass die Aufgabe hochgezogen wird, nur eine Erklärung, ziemlich verloren.

Antwort

0

makeFunc selbst gibt eine Funktion zurück, die erst nach der Zuweisung test = 9999; aufgerufen wird. Auf die Variable test wird vom 'äußeren' Kontext (durch Schließen) zugegriffen.

1

Von the article you linked:

Der Grund dafür ist, dass die Funktionen in JavaScript Form Verschlüsse. Eine Closure ist die Kombination einer Funktion und der lexikalischen Umgebung, in der diese Funktion deklariert wurde. Diese Umgebung besteht aus lokalen Variablen, die zum Zeitpunkt der Erstellung der Sperrung vorhanden waren.

Hier ist name geschlossen: Es ist eine lokale Variable zu der Zeit, als die Funktion erstellt wurde. Es ist zwar keine perfekte Analogie, aber Sie können sich vorstellen, dass die Funktion displayName einen internen Zeiger auf den Stack-Frame hat, der alle lokalen Variablen enthält, die bei der Definition der Funktion vorhanden waren. Wenn Sie name übergeben, könnten Sie sehen, dass es aufbewahrt wird.

var test = 1; 
 

 
function makeFunc(name) { 
 
    function displayName() { 
 
    alert(name + ' ' + test); 
 
    } 
 
    return displayName; 
 
} 
 

 
//Create myFunction - test should still be set to 1 at this point 
 
var myFunc = makeFunc("one"); 
 
var myFunc2 = makeFunc("two"); 
 

 
test = 99999; 
 

 
myFunc(); // combines closed-over name "one" with lexical scope test 99999 
 
myFunc2(); // combines closed-over name "two" with lexical scope test 99999

Da test ist in lexikalischen Gültigkeitsbereich, kein geschlossener über lokale Variable, die beide makeFunc und makeFunc2 den gleichen Wert in der globalen Rahmen manipulieren, dass test Zurücksetzen bedeutet die Ausgabe manipulieren kann auch nach Sie haben die Schließungen erstellt.

0

Ein Abschluss erfasst nicht nur einen Schnappschuss von test, wenn er erstellt wird, sondern erfasst die gesamte Variable selbst. Dies bedeutet, dass bei jedem Aufruf der Funktion myFunc der Wert test beim Aufruf, nicht der Wert test beim Erstellen des Abschlusses ausgegeben wird.

Mit anderen Worten, innerhalb der Schließung ist test immer noch eine Variable, kein Wert. Das bedeutet, dass es geändert und manipuliert werden kann, wie Sie wollen, und alles, was es verwendet, wird diese Änderungen sehen.

Also für Ihren Code, sobald Sie myFunc() in der letzten Zeile aufrufen, wird die Laufzeit der Ausdruck name + ' ' + test, bewerten und da nun Test 99999 ist, das ist, was man bekommt.

0

Dies ist, weil test nicht aktualisiert wird, wenn makeFunc()displayName zurückgibt.

Werfen Sie einen Blick auf name, die ich von der Methode makeFunc() Bereich auf den globalen Bereich entfernt. Wenn makeFunc() ausgeführt wird, wird name innerhalb des Methodenbereichs auf Mozilla aktualisiert.makeFunc() gibt dann die Funktion displayName() ohne Berühren/Aktualisieren test zurück. test wird nur nach der Deklaration von var myFunc = displayName() // return value of makeFunc() aktualisiert.

den Wert test nach der Erklärung der myFunc() ändern, wird der Wert von console.log()test dann verändern.

var test = 1; 
 
var name = "IE"; 
 

 
function makeFunc() { 
 
    name = 'Mozilla'; 
 
    console.log("test inside makeFunc(): " + test); 
 
    function displayName() { 
 
    console.log(name + ' ' + test); 
 
    } 
 
    return displayName; 
 
} 
 

 
//Create myFunction - test should still be set to 1 at this point 
 
console.log("test before myFunc declaration: " + test); 
 
console.log("name before myFunc declaration: " + name); 
 
var myFunc = makeFunc(); 
 
console.log("test after myFunc declaration: " + test); 
 
console.log("name after myFunc declaration: " + name); 
 

 
console.log("myFunc() before updating test"); 
 
myFunc(); 
 
test = 99999; 
 
console.log("myFunc() after updating test"); 
 
myFunc();

Verwandte Themen