Dieser Code funktioniert auch in verschiedenen Browsern immer:
function fooCheck() {
alert(internalFoo()); // We are using internalFoo() here...
return internalFoo(); // And here, even though it has not been defined...
function internalFoo() { return true; } //...until here!
}
fooCheck();
Ich konnte jedoch keinen einzigen Hinweis darauf finden, warum es funktionieren sollte. Ich habe dies zum ersten Mal in John Resigs Präsentationsnotiz gesehen, aber es wurde nur erwähnt. Es gibt dort oder irgendwo keine Erklärung dafür.
Könnte mich bitte jemand aufklären?
javascript
function
Edu Felipe
quelle
quelle
Antworten:
Die
function
Deklaration ist magisch und bewirkt, dass ihre Kennung gebunden wird, bevor etwas in ihrem Codeblock * ausgeführt wird.Dies unterscheidet sich von einer Zuordnung mit einem
function
Ausdruck, der in normaler Top-Down-Reihenfolge ausgewertet wird.Wenn Sie das Beispiel geändert haben, um zu sagen:
es würde aufhören zu arbeiten.
Die Funktionsdeklaration ist syntaktisch ziemlich unabhängig vom Funktionsausdruck, obwohl sie fast identisch aussieht und in einigen Fällen mehrdeutig sein kann.
Dies ist im ECMAScript-Standard , Abschnitt 10.1.3, dokumentiert . Leider ist ECMA-262 selbst nach Standards kein sehr lesbares Dokument!
*: die enthaltende Funktion, den Block, das Modul oder das Skript.
quelle
Es heißt HOISTING - Aufrufen (Aufrufen) einer Funktion, bevor sie definiert wurde.
Zwei verschiedene Arten von Funktionen, über die ich schreiben möchte, sind:
Ausdrucksfunktionen und Deklarationsfunktionen
Ausdrucksfunktionen:
Funktionsausdrücke können in einer Variablen gespeichert werden, sodass sie keine Funktionsnamen benötigen. Sie werden auch als anonyme Funktion (eine Funktion ohne Namen) benannt.
Um diese Funktionen aufzurufen (aufzurufen), benötigen sie immer einen Variablennamen . Diese Art von Funktion funktioniert nicht, wenn sie aufgerufen wird, bevor sie definiert wurde, was bedeutet, dass hier kein Heben stattfindet. Wir müssen immer zuerst die Ausdrucksfunktion definieren und sie dann aufrufen.
So können Sie es in ECMAScript 6 schreiben:
Deklarationsfunktionen:
Mit der folgenden Syntax deklarierte Funktionen werden nicht sofort ausgeführt. Sie werden "zur späteren Verwendung gespeichert" und später ausgeführt, wenn sie aufgerufen (aufgerufen) werden. Diese Art von Funktion funktioniert, wenn Sie sie VOR oder NACH der Definition aufrufen. Wenn Sie eine Deklarationsfunktion aufrufen, bevor sie definiert wurde, funktioniert das Heben ordnungsgemäß.
Hebebeispiel:
quelle
let fun = theFunction; fun(); function theFunction() {}
wird auch funktionieren (Knoten und Browser)Der Browser liest Ihren HTML-Code von Anfang bis Ende und kann ihn ausführen, während er gelesen und in ausführbare Blöcke (Variablendeklarationen, Funktionsdefinitionen usw.) analysiert wird. Er kann jedoch zu jedem Zeitpunkt nur das verwenden, was vor diesem Punkt im Skript definiert wurde.
Dies unterscheidet sich von anderen Programmierkontexten, die Ihren gesamten Quellcode verarbeiten (kompilieren), ihn möglicherweise mit Bibliotheken verknüpfen, die Sie zum Auflösen von Referenzen benötigen, und ein ausführbares Modul erstellen, an dem die Ausführung beginnt.
Ihr Code kann auf benannte Objekte (Variablen, andere Funktionen usw.) verweisen, die weiter unten definiert sind. Sie können jedoch keinen Referenzcode ausführen, bis alle Teile verfügbar sind.
Wenn Sie sich mit JavaScript vertraut machen, werden Sie sich genau bewusst, dass Sie die Dinge in der richtigen Reihenfolge schreiben müssen.
Revision: Um die akzeptierte Antwort (oben) zu bestätigen, verwenden Sie Firebug, um den Skriptabschnitt einer Webseite zu durchlaufen. Sie werden sehen, dass es von Funktion zu Funktion springt und nur die erste Zeile besucht, bevor es tatsächlich Code ausführt.
quelle
Einige Sprachen verlangen, dass Bezeichner vor der Verwendung definiert werden. Ein Grund dafür ist, dass der Compiler einen einzigen Durchgang für den Quellcode verwendet.
Wenn es jedoch mehrere Durchgänge gibt (oder einige Schecks verschoben werden), können Sie ohne diese Anforderung perfekt leben. In diesem Fall wird der Code wahrscheinlich zuerst gelesen (und interpretiert) und dann werden die Links gesetzt.
quelle
Ich habe nur wenig JavaScript verwendet. Ich bin mir nicht sicher, ob dies helfen wird, aber es sieht dem, worüber Sie sprechen, sehr ähnlich und kann einen Einblick geben:
http://www.dustindiaz.com/javascript-function-declaration-ambiguity/
quelle
Der Hauptteil der Funktion "internalFoo" muss zur Analysezeit irgendwohin gehen. Wenn also der Code vom JS-Interpreter gelesen (auch als Analyse bezeichnet) wird, wird die Datenstruktur für die Funktion erstellt und der Name zugewiesen.
Erst später, wenn der Code ausgeführt wird, versucht JavaScript tatsächlich herauszufinden, ob "internalFoo" existiert und was es ist und ob es aufgerufen werden kann usw.
quelle
Aus dem gleichen Grund wird
foo
im globalen Namespace immer Folgendes eingefügt:quelle
if
Block erstellt keinen Bereich, während einfunction()
Block immer einen erstellt. Der wahre Grund war, dass die Definition globaler Javascript-Namen in der Kompilierungsphase erfolgt, sodass der Name auch dann definiert wird, wenn der Code nicht ausgeführt wird. (Entschuldigung, der Kommentar hat so lange gedauert)