Alle machen ungefähr dasselbe, mit ein paar subtilen Unterschieden:
Es gibt eine Unterscheidung zwischen dem Funktionsnamen und der Variablen, der die Funktion zugewiesen ist. Der Funktionsname kann nicht geändert werden, während die Variable, der die Funktion zugewiesen ist, neu zugewiesen werden kann. Der Funktionsname kann nur im Hauptteil der Funktion verwendet werden. Der Versuch, es außerhalb des Funktionskörpers zu verwenden, führt zu einem Fehler (oder undefined
wenn der Funktionsname zuvor über eine var
Anweisung deklariert wurde)., Beispiel:
var y = function x() {};alert(x); // throws an error
Der Funktionsname wird auch angezeigt, wenn die Funktion über die toString-Methode von Function
serialisiert wird.
Andererseits ist die Variable, der die Funktion zugewiesen ist, nur durch ihren Gültigkeitsbereich begrenzt, der garantiert den Gültigkeitsbereich enthält, in dem die Funktion deklariert ist.
Wie das 4. Beispiel zeigt, kann der Funktionsname von der Variablen abweichen, der die Funktion zugewiesen ist. Sie haben keine Beziehung zueinander. Eine Funktionsdeklaration erstellt auch eine Variable mit demselben Namen wie der Funktionsname., Im Gegensatz zu den durch Funktionsausdrücke definierten Funktionen kann daher auf Funktionen, die durch Funktionsdeklarationen definiert sind, über ihren Namen in dem Bereich zugegriffen werden, in dem sie definiert wurden:
Eine Funktion, die durch ‚new Function'
definiert ist, hat keinen Funktionsnamen. In der SpiderMonkey-JavaScript-Engine wird die serialisierte Form der Funktion jedoch so angezeigt, als hätte sie den Namen „anonymous“. Zum Beispiel gibt alert(new Function())
aus:
function anonymous() {}
Da die Funktion tatsächlich keinen Namen hat, ist anonymous
keine Variable, auf die innerhalb der Funktion zugegriffen werden kann., Beispielsweise würde Folgendes zu einem Fehler führen:
var foo = new Function("alert(anonymous);");foo();
Im Gegensatz zu Funktionen, die durch Funktionsausdrücke oder durch den Konstruktor Function
definiert sind, kann eine durch eine Funktionsdeklaration definierte Funktion vor der Funktionsdeklaration selbst verwendet werden. Beispiel:
foo(); // alerts FOO!function foo() { alert('FOO!');}
Eine Funktion, die durch einen Funktionsausdruck oder eine Funktionsdeklaration definiert wird, erbt den aktuellen Bereich. Das heißt, die Funktion bildet einen Abschluss., Andererseits erbt eine Funktion, die durch einen Function
Konstruktor definiert wird, keinen anderen Bereich als den globalen Bereich (den alle Funktionen erben).
Funktionen, die durch Funktionsausdrücke und Funktionsdeklarationen definiert sind, werden nur einmal analysiert, während die durch den Function
Konstruktor definierten nicht. Das heißt, die an den Konstruktor Function
übergebene Funktionskörperzeichenfolge muss bei jedem Aufruf des Konstruktors analysiert werden., Obwohl ein Funktionsausdruck jedes Mal einen Abschluss erstellt, wird der Funktionskörper nicht wiederhergestellt, sodass Funktionsausdrücke immer noch schneller sind als „new Function(...)
„. Daher sollte der Function
Konstruktor im Allgemeinen wann immer möglich vermieden werden.
Es sollte jedoch beachtet werden, dass Funktionsausdrücke und Funktionsdeklarationen, die in der Funktion verschachtelt sind, die durch Parsen einer Function constructor
– Zeichenfolge generiert wird, nicht wiederholt analysiert werden. Zum Beispiel:
Eine Funktionsdeklaration wird sehr leicht (und oft unbeabsichtigt) in einen Funktionsausdruck umgewandelt., Eine Funktionsdeklaration hört auf, eine zu sein, wenn sie entweder:
- wird Teil eines Ausdrucks
- ist kein „Quellelement“ einer Funktion oder des Skripts selbst mehr. Ein „Quellelement“ ist eine nicht verschachtelte Anweisung im Skript oder ein Funktionskörper: