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 varAnweisungen "werfen" die Erstellung von fooganz 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 foowird 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 foowird 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 fooangehoben, die Zuweisung erfolgt dort, wo sie im "ursprünglichen" (nicht angehobenen) Code enthalten ist. Wenn baraufgerufen wird, wird ihm vorher fooein Wert zugewiesen, also foo === undefined. Jetzt im Funktionskörper von barist es so, als ob Sie es tun undefined(), was einen Fehler auslöst.