2013-02-22 11 views
5

Ich lese den Ausführungskontext/Lexikalische Umgebung Abschnitt der ECMA 262 5 specification. Es gibt die folgenden: (Hervorhebung hinzugefügt)Hat ein Funktionsausdruck einen eigenen Bereich/lexikalische Umgebung?

A lexikalische Umgebung ist eine Spezifikation Typ verwendet, um die Assoziation von Identifikatoren auf bestimmte Variablen und Funktionen auf die lexikalische Verschachtelungsstruktur von ECMAScript-Code basiert zu definieren. Eine Lexikalische Umgebung besteht aus einem Umgebungsdatensatz und einem möglicherweise Nullbezug auf eine äußere Lexikalische Umgebung. Normalerweise ist eine Lexikalische Umgebung mit einer bestimmten syntaktischen Struktur von ECMAScript-Code wie einer FunctionDeclaration, einer WithStatement- oder einer Catch-Klausel eines TryStatements assoziiert, und jedes Mal, wenn ein solcher Code evaluiert wird, wird eine neue Lexical-Umgebung erstellt.

Ich bemerkte, dass es nichts über das Erstellen einer lexikalischen Umgebung für Funktionsausdrücke sagt. Wird eine lexikalische Umgebung für Funktionsausdrücke erstellt oder nur für Funktionsdeklarationen erstellt? Fehle ich etwas?

Bearbeiten: Ich stelle fest, dass Funktionscode its own execution context haben wird, weshalb ich auch verwirrt bin, warum Funktionsausdruck in der lexikalischen Umgebung nicht erwähnt wird.

+4

Da die Liste der Beispiele mit "wie" beginnt, denke ich nicht, dass sie erschöpfend sein sollen. – Pointy

+0

[Abschnitt 13] (http://www.ecma-international.org/ecma-262/5.1/#sec-13) scheint vorzuschlagen, dass neue lexikalische Umgebungen nur für Funktionsausdrücke mit Namen (und nicht für anonyme Funktionen) erstellt werden Ausdrücke oder Funktionsdeklarationen). Aber ich muss es falsch interpretieren. –

Antwort

3

Ja, jede Funktion bekommt (§10.4.3) seine eigene ExecutionContext wenn es heißt (§13.2.1). Dieser neue Kontext wird mit einer neuen LexicalEnvironment (erzeugt durch NewDeclarativeEnvironment, §10.2.2.2) initialisiert, die von der [[Scope]] der Funktion abgeleitet ist - d. H. Die LexicalEnvironment wurde in (§13) deklariert/"ausgedrückt".

Wie @Pointy darauf hingewiesen hat, listet der Satz, auf den Sie gestolpert sind, sie nicht erschöpfend auf: "... einige [Struktur] wie ...".

2

Eine instanziierte Funktion hat einen Gültigkeitsbereich. Es spielt keine Rolle, ob es als Teil einer Funktionsdeklarationsanweisung oder eines Funktionsinstanziierungsausdrucks instanziiert wurde.

(es ist wohl richtiger zu sagen, dass eine instanziiert Funktion einen Umfang hat wenn es genannt wird, und dass jeder Aufruf erzeugt einen verschiedenen Umfang.)

3

Wenn ein Name in einer FunctionExpression enthalten ist, wird dieser Name eine schreibgeschützte Bindung, die alle äußeren Deklarationen desselben Namens schattiert. Diese Bindung kann jedoch selbst durch einen formalen Parameter oder eine lokale Deklaration innerhalb der Funktion beschattet werden. Solch eine Bindung für den Funktionsnamen wird nur für den Namen FunctionExpressions und nicht für anonyme FunctionExpressions oder FunctionDeclarations erstellt. Die Namensbindung für eine FunctionDeclaration wird in der umgebenden Variablenumgebung erstellt. Hier

ist ein detaillierteres explantion Referenzierung der ES5.1 spec:

Es gibt mehr als eine Umgebung Datensatz mit einem Funktionsobjekt zugeordnet ist. Wenn eine Funktion aufgerufen wird, wird ein neues DeclarativeEnvironmentRecord erstellt, das die lokalen Bindungen dieses bestimmten Funktionsaufrufs enthält.Dieser Datensatz wird sowohl zur Variablenumgebung als auch zur anfänglichen Lexikalischen Umgebung des ExecutionContext, der für diesen Aufruf erstellt wird. Dies ist in Abschnitt 10.4.3 angegeben.

Wenn dieser Umgebungsdatensatz erstellt wird, wird seine "äußere Umgebung" auf den Wert der internen Eigenschaft [[Scope]] des Funktionsobjekts gesetzt, das aufgerufen wird. (Zeile 5, 10.4.3) Die äußere Umgebung stellt die Bindungen für alle nicht lokalen Deklarationen bereit. Der [[Scope]] wird gesetzt, wenn ein Funktionsobjekt erstellt wird (siehe Semantik in Abschnitt 13 und auch 13.2). Jeder unterschiedliche Aufruf eines bestimmten Funktionsobjekts hat also eine andere lokale Umgebung, aber alle Aufrufe dieser Funktion teilen dasselbe äußere [[Scope]].

Für die meisten Funktionen ist das erfasste [[Scope]] einfach die LexicalEnvironment des ExecutionContext, die beim Erstellen der Funktion aktiv war. Jedoch FunctionExpressions, die eine Kennung als Funktionsname enthalten eine zusätzliche DeclarativeEnvironmentRecord einfügen am Anfang seiner Kette [[Scope]]. (Siehe Schritte 1-3 des dritten Algorithmus in Abschnitt 13).

Dieser zusätzliche Umgebungsdatensatz wird verwendet, um die Bindung für den Funktionsnamen zu erfassen, der in der FunctionExpression angegeben ist.