2015-05-15 7 views
6

Ich verstehe, dass jede Funktion in JavaScript ein erstklassiges Objekt ist und eine interne Eigenschaft [[scope]] hat, die die Bindungsdatensätze der freien Variablen der Funktion enthält. Es gibt jedoch zwei spezielle Fälle.Stimmt es, dass jede Funktion in JavaScript eine Schließung ist?

  1. Ist die Funktion erstellt von Function Constructor auch eine Schließung? Das Funktionsobjekt, das von Function-Konstruktor erstellt wird, ist speziell, da sein [[Bereich]] möglicherweise nicht auf die lexikalischen Umgebungen seiner äußeren Funktionen verweist, sondern nur auf den globalen Kontext. Zum Beispiel

    var a = 1; 
    var fn = (function outer() { 
        var a = 2; 
        var inner = new Function('alert(a); '); 
        return inner; 
    })(); 
    fn(); // will alert 1, not 2. 
    

    Dies ist nicht intuitiv. Wird das auch Schließung genannt?

  2. Wenn eine innere Funktion keine freien Variablen hat, können wir dann sagen, dass eine Schließung gebildet wird, wenn die innere Funktion erzeugt wird? Beispiel:

    In diesem Fall verweist fn auf ein leeres Funktionsobjekt, das als innere Funktion erstellt wurde. Es hat keine freien Variablen. Können wir in diesem Fall sagen, dass ein Verschluss gebildet wird?

+3

Also, was ist Ihre Definition von "closure"? – Bergi

+2

Weitere Kommentare zu diesem Verhalten finden Sie hier: http://www.bennadel.com/blog/1909-jacascript-function-constructor-does-not-create-a-closure.htm Das Verhalten scheint mit 'eval' Verhalten (indirekter oder direkter Anruf). Siehe auch hier: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function --- * "Funktionen, die mit dem Function-Konstruktor erstellt wurden, erzeugen keine Schließungen für ihre Erstellungskontexte; sie werden immer im globalen Bereich erstellt."* –

+1

Frage # 2 ist eher eine philosophische" wenn ein Baum fällt in einem Wald "Frage. – JJJ

Antwort

7

Ist die Funktion von Funktion Konstruktor auch eine Schließung erstellt?

Ja, es schließt über den globalen Bereich. Das kann nicht intuitiv sein, da alle anderen JavaScript-Verschlüsse über ihren lexikalischen Bereich schließen, aber es entspricht immer noch unserer definition of a closure. In Ihrem Beispiel ist a eine freie Variable und wird in einem anderen Bereich in die a aufgelöst, wenn die /fn-Funktion irgendwo aufgerufen wird.

Wenn eine innere Funktion keine freien Variablen hat, können wir sie immer noch als Schließung bezeichnen?

Hängt davon ab, wen Sie fragen. Some sagen ja, others nennen sie "uninteressante Verschlüsse", persönlich sage ich Nein, weil they don't reference ein äußerer Umfang ist.

+0

Dank @Bergi, wunderbare Erklärung. Im zweiten Fall, der Die Funktion outer() wird nach der Ausführung des Codes als Garbage-Collection behandelt, da sie nicht mehr referenziert wird. Aber was ist in der internen Eigenschaft [[scope]] von fn? Oder vereinfacht gesagt, bezieht sich das Funktionsobjekt fn darauf, dass es erstellt wurde im äußeren() Geltungsbereich? –

+0

Nun, wenn Sie die ES5-Spezifikation befolgen, speichert das [[scope]] von "inner" die lexikalische Umgebung von "outer" mit seinen "äußeren" und "a" Variablen - so ist immer noch alles zugänglich Wenn Sie einer tatsächlichen ES-Implementierung folgen und "inner" mit Ihrem Debugger überprüfen, werden keine Bereichsreferenzen angezeigt - sie werden nicht benötigt, da keine freien Variablen vorhanden sind. – Bergi

4

Hinweis: Funktionen, die mit dem Konstruktor Function erstellt werden, erstellen keine -Closures für ihre Erstellungskontexte. Sie werden immer im globalen Gültigkeitsbereich erstellt. Wenn sie ausgeführt werden, können sie nur auf ihre eigenen lokalen und globalen Variablen zugreifen, nicht die aus dem Bereich , in dem der Function-Konstruktor aufgerufen wurde. Dies unterscheidet sich von unter Verwendung von Eval mit Code für einen Funktionsausdruck.

von https://developer.mozilla.org

Verwandte Themen