Ich erinnere mich, dass mir der Interviewer diese Frage gestellt hat, als ich als Praktikant bei Tencent ein Vorstellungsgespräch geführt habe.
In ECMAScript gibt es zwei am häufigsten verwendete Methoden zum Erstellen von Funktionsobjekten, nämlich die Verwendung von Funktionsausdrücken oder die Verwendung von Funktionsdeklarationen. In diesem Zusammenhang macht die ECMAScript-Spezifikation deutlich, dass die Funktionsdeklaration immer einen Bezeichner (Identifier) haben muss, den wir als Funktionsnamen bezeichnen, und der Funktionsausdruck weggelassen werden kann.
Funktionsdeklaration:
2. Erstellen Sie ein Attribut namens Identifier für das aktuelle Variablenobjekt mit dem Wert Result(1).
Funktionsausdruck:
(Funktionsausdrücke werden in anonyme und benannte Funktionsausdrücke unterteilt)
1. Erstellen Sie ein neues Objekt
2. Fügen Sie Result(1) am Anfang der Bereichskette
hinzu
3. Erstellen Sie ein neues Funktionsobjekt, geben Sie die Parameter in FormalParameterList und den Funktionskörper in FunctionBody an. Verwendet die Bereichskette in der aktuell ausgeführten Ausführungsumgebung als Bereich.
4. Erstellen Sie ein Attribut mit dem Namen Identifier für Result(1), sein Wert ist Result(3), schreibgeschützt, kann nicht gelöscht werden
5. Entfernen Sie Result(1)
aus der Bereichskette
6. Ergebnis(3) zurückgeben
Lassen Sie uns kurz über die Ähnlichkeiten und Unterschiede zwischen Funktionsdeklarationen und Funktionsausdrücken sprechen. Es gibt einen subtilen, aber wichtigen Unterschied im Verhalten von Deklarationen und Ausdrücken.
Zuerst werden Funktionsdeklarationen analysiert und ausgewertet, bevor Ausdrücke analysiert und ausgewertet werden. Auch wenn die Deklaration die letzte Zeile im Quellcode ist, wird sie vor dem ersten Ausdruck im gleichen Bereich ausgewertet. Es ist leichter zu verstehen, wenn man sich ein Beispiel anschaut. Im folgenden Beispiel wird die Funktion fn nach Alert deklariert. Wenn jedoch die Warnung ausgeführt wird, ist fn bereits definiert:
Um es kurz zusammenzufassen: Was ist der Unterschied?
2. Ausdrücke werden nur ausgewertet, wenn sie gefunden werden.
das heißt, das Verhalten der Steuerung der Funktionsdeklaration durch bedingte Anweisungen ist nicht standardisiert, sodass in unterschiedlichen Umgebungen unterschiedliche Ergebnisse erzielt werden können. Das heißt:
FunctionDeclaration kann nur in Program oder FunctionBody erscheinen. Syntaktisch gesehen können sie nicht innerhalb eines Blocks ({ ... }) erscheinen, beispielsweise innerhalb einer if-, while- oder for-Anweisung. Weil Block nur Statement enthalten kann, aber kein SourceElement wie FunctionDeclaration.
Wenn Sie sich andererseits die Generierungsregeln genauer ansehen, werden Sie feststellen, dass die einzige Möglichkeit für ein Ausdruck, in einem Block zu erscheinen, darin besteht, ihn zu einem Teil eines ExpressionStatements zu machen. In der Spezifikation heißt es jedoch eindeutig, dass ExpressionStatement nicht mit dem Schlüsselwort function beginnen kann. Was dies tatsächlich bedeutet, ist, dass FunctionExpression nicht in Statement oder Block erscheinen kann (vergessen Sie nicht, dass Block aus Statement besteht).
Aufgrund der oben genannten Einschränkungen sollte eine Funktion, wann immer sie in einem Block erscheint (wie im Beispiel oben), eigentlich als Syntaxfehler und nicht als Funktionsdeklaration oder Ausdruck behandelt werden.
Wann sollten wir also Funktionsdeklarationen oder Funktionsausdrücke verwenden? Funktionsdeklarationen können nur im „Programmcode“ erscheinen, das heißt, sie können nur in anderen Funktionskörpern oder im globalen Raum erscheinen, ihre Definitionen können nicht einer Variablen oder einem Attribut zugewiesen oder als Parameter in einem Funktionsaufruf übergeben werden; Ein Beispiel ist die zulässige Verwendung von Funktionsdeklarationen: foo(), bar() und local() werden alle über den Funktionsdeklarationsmodus deklariert:
Mein Wissen ist begrenzt, bitte korrigieren Sie mich, wenn es Fehler gibt.