tl; dr Wenn Sie nichts anrufen, bis alles geladen ist, sollte es Ihnen gut gehen.
Bearbeiten: Für eine Übersicht, die auch einige ES6-Deklarationen ( let
, const
) abdeckt : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Scope_Cheatsheet
Dieses seltsame Verhalten hängt davon ab
- Wie definieren Sie die Funktionen und
- Wenn Sie sie anrufen.
Hier sind einige Beispiele.
bar(); //This won't throw an error
function bar() {}
foo(); //This will throw an error
var foo = function() {}
bar();
function bar() {
foo(); //This will throw an error
}
var foo = function() {}
bar();
function bar() {
foo(); //This _won't_ throw an error
}
function foo() {}
function bar() {
foo(); //no error
}
var foo = function() {}
bar();
Dies liegt an etwas, das als Heben bezeichnet wird !
Es gibt zwei Möglichkeiten , um Funktionen zu definieren: Funktionsdeklaration und Funktion Ausdruck . Der Unterschied ist ärgerlich und winzig, also sagen wir einfach etwas Falsches: Wenn Sie es so schreiben function name() {}
, ist es eine Deklaration , und wenn Sie es so schreiben var name = function() {}
(oder eine anonyme Funktion, die einer Rückgabe zugewiesen ist, solche Dinge), ist es das eine Funktion Ausdruck .
Schauen wir uns zunächst an, wie mit Variablen umgegangen wird:
var foo = 42;
//the interpreter turns it into this:
var foo;
foo = 42;
Nun, wie Funktionsdeklarationen werden behandelt:
var foo = 42;
function bar() {}
//turns into
var foo; //Insanity! It's now at the top
function bar() {}
foo = 42;
Die var
Anweisungen "werfen" die Erstellung von foo
ganz nach oben, weisen ihr jedoch noch keinen Wert zu. Als nächstes folgt die Funktionsdeklaration, und schließlich wird ein Wert zugewiesen foo
.
Und was ist damit?
bar();
var foo = 42;
function bar() {}
//=>
var foo;
function bar() {}
bar();
foo = 42;
Nur die Deklaration von foo
wird nach oben verschoben. Die Zuordnung erfolgt erst nach dem Anruf bei bar
, wo es war, bevor das gesamte Heben stattgefunden hat.
Und schließlich der Kürze halber:
bar();
function bar() {}
//turns to
function bar() {}
bar();
Nun, was Funktion Ausdrücke ?
var foo = function() {}
foo();
//=>
var foo;
foo = function() {}
foo();
Genau wie reguläre Variablen, zuerst foo
wird erklärt am höchsten Punkt des Bereichs, dann wird ein Wert zugewiesen.
Mal sehen, warum das zweite Beispiel einen Fehler auslöst.
bar();
function bar() {
foo();
}
var foo = function() {}
//=>
var foo;
function bar() {
foo();
}
bar();
foo = function() {}
Wie wir zuvor gesehen haben, wird nur das Erstellen von foo
angehoben, die Zuweisung erfolgt dort, wo sie im "ursprünglichen" (nicht angehobenen) Code enthalten ist. Wenn bar
aufgerufen wird, wird ihm vorher foo
ein Wert zugewiesen, also foo === undefined
. Jetzt im Funktionskörper von bar
ist es so, als ob Sie es tun undefined()
, was einen Fehler auslöst.