Das Wort „Grube“ bedeutet hier „Falle“. Aufgrund der Natur der „schwachen Sprache“ ist JavaScript während der Verwendung äußerst locker und flexibel, aber es ist auch äußerst leicht, in diese Fallstricke zu tappen verborgen, also müssen Sie die Augen offen halten, damit Sie auf dem Weg zum Erlernen und Anwenden von JS reibungslos vorankommen
1. Globale Variablen
JavaScript verwaltet den Umfang durch Funktionen. Innerhalb einer Funktion deklarierte Variablen sind nur innerhalb der Funktion verfügbar und außerhalb der Funktion nicht verfügbar. Andererseits werden globale Variablen außerhalb einer Funktion deklariert oder einfach ohne Deklaration verwendet.
„Einfache Verwendung ohne Deklaration“ bezieht sich auf die Deklaration von Variablen ohne Verwendung des Schlüsselworts var. Wir wissen das bereits sehr gut, um die implizite Generierung globaler Variablen zu vermeiden, indem wir Variablen so oft wie möglich mit dem Schlüsselwort var deklarieren.
Aber denken Sie, dass die Verwendung von var in Ordnung ist? Werfen wir einen Blick auf diese Grube:
function foo() {
var a = b = 0;
// body...
}
Vielleicht haben Sie zwei lokale Variablen erwartet, aber b ist eine echte globale Variable. Warum? Da Zuweisungsvorgänge von rechts nach links erfolgen, entspricht dies also:
function foo() {
var a = (b = 0);
// body...
}
B ist also eine globale Variable.
Füllen Sie die Lücke aus: Variablendeklarationen, am besten einzeln, nicht im Großhandel~_~;
2. Variablendeklaration
Sehen wir uns zunächst die Fallstricke an:
myName = "global";
function foo() {
warning(myName);
var myName = "local ";
Alert(myName);
}
foo();
Auf den ersten Blick erwarten wir, dass die Ergebnisse der beiden Alerts „global“ und „lokal“ sind ", aber die realen Ergebnisse sind "undefiniert" und "lokal". Warum? Da sich Variablen im selben Gültigkeitsbereich (dieselbe Funktion) befinden, werden Deklarationen an die Spitze des Gültigkeitsbereichs verschoben und zuerst analysiert.
Das Ausführungsverhalten des obigen Codeausschnitts könnte also wie folgt aussehen:
function foo() {
var myName;
Alert(myName); // "undefiniert"
myName = "local";
Alert(myName); // "local"
}
Verwenden Sie eine andere Grube, um zu testen, ob Sie Pre-Parsing wirklich verstehen:
if (!("a" in window)) {
var a = 1;
}
alert (a);
Die Deklaration einer Variablen wird an den Anfang des Codes verschoben und ihr wurde noch kein Wert zugewiesen. Geben Sie als Nächstes die if-Anweisung im Fenster ein (a wurde als globale Variable deklariert), sodass das Auswertungsergebnis der Beurteilungsanweisung falsch ist und die if-Anweisung direkt übersprungen wird Der Wert von a ist undefiniert.
var a; // "undefiniert"
console .log("a" in window); // true
if (!("a" in window)) {
var a = 1; // Nicht ausführen
}
alert(a); // "undefiniert"
Füllen Sie die Variablendeklaration aus, es ist am besten, sie manuell an der Spitze des Bereichs zu platzieren Wird sofort zugewiesen, können Sie es zuerst deklarieren und dann zuweisen.
3. Funktionsdeklaration
Funktionsdeklarationen werden ebenfalls an die Spitze des Gültigkeitsbereichs vorgeschoben, vor allen Ausdrücken und Anweisungen analysiert und ausgewertet
alert(typeof foo); // "function"
function foo() {
// body...
}
Sie können vergleichen:
alert(typeof foo); // "undefiniert"
var foo = function () {
// body...
};
Werden Sie, nachdem Sie diese Wahrheit verstanden haben, immer noch in die folgenden Fallstricke geraten?
Funktionstest() {
Warnung ("1 ");
}
test();
function test() {
alarm("2");
}
test( );
Führen Sie das obige Code-Snippet aus und die beiden angezeigten Popup-Fenster zeigen „2“ an. Warum sind sie nicht „1“ bzw. „2“? Ganz einfach: Die Testdeklaration wird vor test() geparst, und da letzteres ersteres überschreibt, ist das Ergebnis beider Ausführungen „2“.
Füllen Sie die Lücke aus: In den meisten Fällen verwende ich Funktionsausdrücke anstelle von Funktionsdeklarationen, insbesondere in einigen Anweisungsblöcken.
4. Funktionsausdrücke
Schauen wir uns zunächst benannte Funktionsausdrücke an, zum Beispiel:
var bar = function foo() {
// body...
};
Es ist zu beachten, dass der Funktionsname nur innerhalb seiner Funktion sichtbar ist. Zum Beispiel die folgenden Fallstricke:
var bar = function foo() {
foo(); // Normaler Betrieb
};
foo(); // Fehler: ReferenceError
Füllen Sie die Lücke: Verwenden Sie benannte Funktionsausdrücke so wenig wie möglich (außer für einige Rekursions- und Debugging-Zwecke) und verwenden Sie Funktionsnamen niemals extern.
5. Selbstausführung von Funktionen
Bei Funktionsausdrücken können Sie diese selbst ausführen, indem Sie () dahinter hinzufügen, und Sie können Parameter in Klammern übergeben, Funktionsdeklarationen jedoch nicht . Fallstrick:
// (1) Das ist nur ein Gruppierungsoperationssymbol, kein Funktionsaufruf!
// Die Funktion hier wurde also nicht ausgeführt, es ist immer noch eine Anweisung
function foo(x) {
warning(x);
}(1);
Die folgenden Codeausschnitte sind jeweils Das Popup-Fenster zeigt während der Ausführung „1“ an, da alles vor (1) ein Funktionsausdruck ist, sodass () hier kein Gruppierungsoperator, sondern ein Operator ist, der die Aufrufausführung anzeigt.
// Standardanonymer Funktionsausdruck
var bar = function foo(x) {
warning(x);
}(1);
// Die vorherige () wandelt die Funktionsdeklaration in einen Ausdruck um
(function foo(x) {
Alert(x);
})(1);
// Das Ganze () ist der Ausdruck
(function foo(x) {
Alert(x) ;
}(1));
// neuer Ausdruck
neue Funktion foo(x) {
warning(x);
}(1);
// &&, ||, !, , -, ~-Operatoren (und Kommas) machen Funktionsausdrücke und Funktionsdeklarationen eindeutig.
// Sobald der Parser weiß, dass einer von ihnen bereits ein Ausdruck ist, werden alle anderen standardmäßig verwendet zu Ausdrücken
true && function foo(x) {
warning(x);
}(1);
Füllen Sie die Grube: Diese Grube Der Schlüssel liegt darin, die Essenz von zu verstehen verschiedene Funktionsausdrücke.
6. Schließungen in Schleifen
Das Folgende zeigt eine häufige Gefahr:
Dokument beim Klicken auf die Links unten wird die Nummer seiner Sequenz angezeigt
< ;ul>
link #0 link #1 link #2 Link #3 Link #4
var links = document.getElementsByTagName("ul")[ 0].getElementsByTagName("a");
for (var i = 0, l = links.length; i < l; i ) {
links[i].onclick = function (e ) {
e.preventDefault();
warning("You click link #" i);
}
}
我们预期当点击第 i 个链接时,得到此序列索引 i 的值,可实际无论点击哪个链接,得到的都是 i 在循环后的最终结果: „5“。
解释一下原因:当 Warnung 被调用时, für 循环内的匿名函数表达式,保持了对外部变量. i的引用(闭包),此时循环已结束,i 的值被修改为 „5“ 。
填坑:为了得到想要的结果,需要在每次循环中创建变量 i >
Document zeigen Sie beim Klicken auf die unten stehenden Links die Anzahl an seine Sequenz