benannte JavaScript-Funktionsausdrücke – Bereichszugänglichkeit [duplicate]

Lesezeit: 4 Minuten

benannte JavaScript Funktionsausdrucke Bereichszuganglichkeit duplicate
Ducin

Ich folge John Resigs Secrets of JS Ninja-Folien und ich habe etwas gefunden, das ich nicht ganz verstehe. Der folgende Code definiert a benannter Funktionsausdruck:

var ninja = function myNinja(){
  console.log(myNinja); // function myNinja() {...}
};
myNinja; // undefined

Wie ich sehen kann, im aktuellen Bereich (angenommen, es ist global), ninja ist die Variable, die auf die benannte Funktion verweist myNinja. ninja Variable ist im Geltungsbereich zugänglich – das ist klar, aber myNinja ist im Gültigkeitsbereich nicht zugänglich (aber innerhalb seiner eigenen Funktion). Woher?

Wenn ich eine Funktion definiere (nicht mit einem Funktionsausdruck, sondern mit einer Funktionsdeklaration):

function Cheese() {
  console.log(Cheese);
}

dann ist es im aktuellen Bereich zugänglich. Ich weiß, dass das einfach so funktioniert – aber kann jemand erklären, warum das so ist?

  • kangax.github.io/nfe/#named-expr

    – zerkms

    3. Juli 2013 um 11:25 Uhr


  • “kann jemand erklären warum das so ist” Wenn Sie nach dem Grund für diese Designentscheidung fragen, sollten Sie sich an jemanden wenden, der am ECMAScript-Standard arbeitet.

    – Felix Klinge

    3. Juli 2013 um 11:28 Uhr

  • @FelixKling Hallo, wir sehen uns wieder! Kopieren Sie den Kommentar von meiner Frage?

    – Yuan

    3. Juli 2013 um 11:30 Uhr

  • @FelixKling Nun, es geht nicht um Designentscheidungen 🙂 Ich möchte nur verstehen, wie dieses Konzept intern funktioniert, nicht warum jemand in ECMA dieses Konzept mochte;)

    – Ducin

    3. Juli 2013 um 11:33 Uhr

  • @tkoomzaaskz: In diesem Fall finden Sie die technische Erklärung in der Spezifikation: es5.github.io/#x13. Es heißt ausdrücklich: “Die Identifier in einem FunctionExpression kann von innen verwiesen werden FunctionExpression‘S FunctionBody damit sich die Funktion rekursiv selbst aufruft. Doch anders als in a FunctionDeclarationder Identifier in einem FunctionExpression kann nicht referenziert werden und wirkt sich nicht auf den Bereich aus, der die einschließt FunctionExpression.”

    – Felix Klinge

    3. Juli 2013 um 11:38 Uhr


benannte JavaScript Funktionsausdrucke Bereichszuganglichkeit duplicate
Naota

In seinem Buch Die Geheimnisse des JavaScript-Ninjamacht John Resig eine wunderbare Erklärung zu diesem Konzept.

http://jsninja.com/

Nachfolgend die Zitate aus dem Buch:

4.2.4. Benannte Inline-Funktionen

 <script type="text/javascript">
  var ninja = function myNinja(){ 
      assert(ninja == myNinja, "this is named two things at once!"); 
  };
  ninja(); 
  assert(typeof myNinja == "undefined",
    "But myNinja isn't defined outside of the function."); 
 </script>

Diese Auflistung bringt den wichtigsten Punkt in Bezug auf Inline-Funktionen hervor: Obwohl Inline-Funktionen benannt werden können, sind diese Namen nur innerhalb der Funktionen selbst sichtbar.

Erinnern Sie sich an die Scoping-Regeln, über die wir in Kapitel 3 gesprochen haben? Inline-Funktionsnamen verhalten sich ähnlich wie Variablennamen, und ihr Geltungsbereich ist auf die Funktion beschränkt, in der sie deklariert sind.

3.2.1. Umfang und Funktionen

Variablendeklarationen sind ab ihrem Deklarationspunkt im Gültigkeitsbereich bis zum Ende der Funktion, in der sie deklariert sindunabhängig von der Blockverschachtelung.

Wenn Sie mehr über dieses Konzept erfahren möchten, wird Ihnen dieses Buch dabei helfen.

1647146108 67 benannte JavaScript Funktionsausdrucke Bereichszuganglichkeit duplicate
Bergi

warum ist das so?

Ein Funktionsausdruck erstellt bei jeder Auswertung ein neues Funktionsobjekt. Was mit diesem Ergebnis passiert, ist zunächst irrelevant. Aber…

var ninja;
// myNinja; - what would you expect it to be here?
for (var i=0; i<5; i++)
    ninja = function myNinja(){
        console.log(myNinja);
    };
// myNinja; - *which one* would you expect it to be here?
ninja();

Der Aufruf an ninja() ist offensichtlich, es verweist auf die Funktion, die dieser Variablen zuletzt zugewiesen wurde. Und das myNinja in dem console.log verweist auf die Strom Funktionsobjekt – es ist in seinem eigen Umfang.

Aber die myNinja Bezeichner wäre außerhalb der Funktion selbst mehrdeutig.

Im Gegensatz dazu ist eine Funktionsdeklaration hochgezogen und vom gesamten Gültigkeitsbereich aus zugänglich. Sein Bezeichner bezieht sich eindeutig auf das einzelne Funktionsobjekt, das einmalig bei der Initialisierung des Geltungsbereichs erstellt wird.

Stellen Sie sich vor, dass Sie, wenn Sie einfach eine Funktion (Käse) definieren, den aktuellen Gültigkeitsbereich mitteilen: „Ich möchte, dass Sie diese Funktion kennen, ihr Name ist Käse Im Grunde das Gleiche, also ist Ihre neue Funktion (myNinja) jetzt nur im aktuellen (Ninja-)Bereich bekannt …

  • Ich versuche deine Erklärung zu verstehen. Ich weiß, dass, wenn die Steuerung in eine neue Funktion in Javascript übergeht, ein neuer Bereichskontext erstellt und ein neues Variablenobjekt daran angehängt wird – das ist klar. Jetzt hast du geschrieben: Wenn Sie die var ninja verwenden, haben Sie es jetzt mit dem ninja-Bereich zu tun – meinen Sie, dass es einen neuen Gültigkeitsbereich für die Variable (keine Funktion) gibt, wenn ich eine neue Variable deklariere (und in diesem Fall bezieht sich die Variable auf eine Funktion)?

    – Ducin

    3. Juli 2013 um 11:36 Uhr

Name ist eine Eigenschaft des Funktionsobjekts. Wenn Sie eine Funktionsinstanz im Debugger untersuchen, sehen Sie a name Eigentum darauf. Bei Funktionen, die im globalen Gültigkeitsbereich definiert sind, ist der Wert von name wird automatisch als Name der Eigenschaft von verwendet
window Objekt, von dem es referenziert wird.

Im Fall einer Inline-Funktion definieren Sie den Namen der Eigenschaft, mit der auf die Funktion verwiesen wird. Die JS-Engine muss die nicht verwenden name -Eigenschaft aus der Function-Instanz.

995950cookie-checkbenannte JavaScript-Funktionsausdrücke – Bereichszugänglichkeit [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy