In JavaScript sind Ausdrücke Phrasen und Aussagen sind der gesamte Satz oder Befehl. So wie eine englische Aussage mit einem Zeitraum endet, endet JavaScript mit einem Semikolon.
Der Ausdruck berechnet einen Wert, aber die Aussage lässt etwas geschehen.
Eine Möglichkeit, "etwas möglich zu machen", besteht darin, Ausdrücke mit Nebenwirkungen zu berechnen. Ausdrücke mit Nebenwirkungen wie Zuweisungen und Funktionsaufrufen können als separate Anweisungen verwendet werden. Diese Verwendung von Ausdrücken als Aussagen wird auch als Expressions -Anweisungen bezeichnet. Ähnliche Aussagen umfassen Erklärungserklärungen, mit denen neue Variablen deklariert oder neue Funktionen definiert werden.
Ein JavaScript -Programm ist eine Sammlung einer Reihe von ausführbaren Anweisungen. Standardmäßig wird der JavaScript -Interpreter in der Reihenfolge des Schreibens nacheinander ausgeführt. Eine andere Möglichkeit, "etwas möglich zu machen", besteht darin, die Standardausführungsreihenfolge der Anweisung zu ändern:
1. Bedingte Anweisung: Der JavaScript -Interpreter kann bestimmen, ob diese Anweisungen ausgeführt oder überspringen sollen, z. B. wenn und Anweisungen.
2. Loop -Anweisung: Anweisungen, die wiederholt ausgeführt werden können, z. B. während und für Aussagen
3. Jump Anweisung: Sie können den Interpreter in andere Teile des Programms springen lassen, um die Ausführung fortzusetzen, z. B. Break-, Rückkehr- und Wurfanweisungen
Als nächstes wird dieser Artikel verschiedene Aussagen und ihre Syntax in JavaScript einführen. Dieses Kapitel fasst diese Sätze am Ende zusammen. Ein JavaScript -Programm ist nichts anderes als eine Sammlung von Aussagen, die durch Trennung getrennt sind. Sobald Sie die JavaScript -Anweisungen beherrschen, können Sie ein JavaScript -Programm schreiben.
1. Ausdruckserklärung
Zuweisungsanweisungen sind eine relativ wichtige Ausdruckserklärung. Ihre Funktion besteht darin, den Wert einer Variablen zu ändern, genau wie die Ausführung einer Zuweisungsanweisung: Zum Beispiel: zum Beispiel
Die Codekopie lautet wie folgt:
Greet = "Hallo" + Name;
i *= 3;
Der Inkrementoperator (++) und der abnehmende Operator (-) beziehen sich auf die Zuweisungsanweisung. Ihre Funktion besteht darin, den Wert einer Variablen zu ändern, genau wie die Ausführung einer Zuweisungsanweisung.
Die Codekopie lautet wie folgt:
Zähler ++;
Die wichtige Funktion des Löschbetreibers besteht darin, die Eigenschaften eines Objekts (oder die Elemente eines Arrays) zu löschen.
Die Codekopie lautet wie folgt:
Ochsen löschen;
Funktionsaufrufe sind beispielsweise eine weitere Hauptkategorie von Ausdrucksanweisungen
Die Codekopie lautet wie folgt:
Alarm (Greet);
Fenster.CLOSE ();
Obwohl diese Clientfunktionen Ausdrücke sind, haben sie einen gewissen Einfluss auf den Webbrowser. Wir glauben also, dass es sich auch um eine Aussage handelt, und es ist nicht sinnvoll, eine Funktion ohne Nebenwirkungen aufzurufen, es sei denn, es ist beispielsweise Teil eines komplexen Ausdrucks oder einer Zuweisungsanweisung. Es ist unmöglich, zufällig einen Cosinus -Wert zu verwerfen;
Math.cos (x);
Um den Cosinus -Wert zu erhalten, müssen Sie ihn stattdessen einer Variablen zuweisen, damit dieser Wert in Zukunft verwendet werden kann:
var cx = math.cos (x);
Wieder endet jede Codezeile mit einem Semikolon.
2. Zusammengesetzte Aussagen und leere Aussagen
Mehrere Ausdrücke können zusammen mit einem Kommasoperator verkettet werden, um einen Ausdruck zu bilden. In ähnlicher Weise kann JavaScript Ihnen auch sagen, dass mehrere Aussagen zusammen vereint sind, um eine zusammengesetzte Anweisung zu bilden. Wickeln Sie einfach mehrere Aussagen in lockige Klammern ein. Daher können die folgenden Codezeilen als separate Anweisung überall in JavaScript verwendet werden, die Sie für eine Anweisung verwenden möchten.
Die Codekopie lautet wie folgt:
{
x = math.pi;
cx = math.cos (x);
console.log ("cos (π) =" + cx);
}
Zu den Anweisungsblöcken müssen mehrere Punkte beachtet werden: Erstens erfordern Anweisungsblöcke keine Semikolons. Elementanweisungen in Blöcken müssen mit Semikolonen enden, Anweisungsblöcke jedoch nicht.
Zweitens sind die Zeilen im Anweisungsblock eingereicht, was nicht erforderlich ist, aber eine nette Einklingung kann den Code lesbarer und einfacher zu verstehen.
Drittens hat JavaScript keinen Umfang auf Blockebene, und die im Anweisungsblock deklarierten Variablen sind nicht privat im Anweisungsblock gehören. (Weitere Informationen finden Sie im ersten Abschnitt von Kapitel 3, 10)
Die Praxis, viele Aussagen in einen großen Anweisungsblock zu kombinieren, ist bei der JavaScript -Programmierung sehr häufig. Ähnliche Ausdrücke enthalten normalerweise Subexpressionen, viele JavaScripts enthalten andere Substatatemente. In Form von Form kann JavaScript normalerweise einen Anweisungsblock einen Substatement enthalten. Zum Beispiel: Der while -Schleifenkörper kann nur eine Anweisung enthalten. Mit einem Anweisungsblock können Sie eine beliebige Anzahl von Anweisungen in diesen Block einfügen, und dieser Anweisungsblock kann als Anweisung verwendet werden.
Verwenden Sie in JavaScript, wenn mehrere Anweisungen als eine Anweisung verwendet werden sollen, stattdessen eine konforme Anweisung. Eine leere Anweisung (leere Anweisung) ist genau das Gegenteil, sie ermöglicht 0 Anweisungen. Die leere Aussage sieht so aus:
;//Semikolon
Der JavaScript -Interpreter führt bei der Ausführung einer leeren Aussage offensichtlich keine Aktionen aus, aber die Praxis hat bewiesen, dass leere Aussagen manchmal nützlich sind
Die Codekopie lautet wie folgt:
// Initialisieren Sie ein Array a
für (i = 0; i <a.länge; a [i ++] = 0);
In dieser Schleife sind alle Operationen im Ausdruck A [i ++] = 0 abgeschlossen, und hier wird kein Schleifenkörper benötigt. JavaScript verlangt jedoch, dass die Schleifenkörper mindestens eine Aussage enthält, sodass hier nur ein separates Semikolon verwendet wird, um eine leere Aussage darzustellen.
Beachten Sie, dass die Semikolons auf der rechten Seite der für die Schleife, während der Schleife oder bei der Anweisung unauffällig sind, was einige tödliche Fehler verursachen kann, die schwer zu lokalisieren sind. Zum Beispiel ist das Ausführungsergebnis des folgenden Code wahrscheinlich ein Effekt, den der Autor nicht möchte:
Die Codekopie lautet wie folgt:
if ((a == 0) || (b == 0)); // Diese Codezeile macht nichts ...
o = null; // Diese Codezeile wird immer ausgeführt
Wenn Sie eine leere Anweisung für besondere Zwecke verwenden, ist es am besten, Kommentare in den Code hinzuzufügen, was deutlich darauf hinweisen kann, dass diese leere Anweisung nützlich ist.
Die Codekopie lautet wie folgt:
für (i = 0; i <a.länge; a [i ++] = 0) /*leer* /;
3.. Erklärung der Erklärung
VAR und Funktion sind Deklarationsanweisungen, die Variablen oder Funktionen deklarieren oder definieren. Diese Aussagen definieren und weisen ihnen Bezeichner (variable Namen und Funktionsnamen) ab, die überall im Programm verwendet werden können. Deklarationsaussagen tun selbst nichts, aber es hat eine wichtige Bedeutung: Durch das Erstellen von Variablen und Funktionen kann die Semantik des Codes besser organisiert werden.
In den folgenden Abschnitten werden über VAR -Anweisungen und Funktionsanweisungen gesprochen, aber nicht alle Inhalte von Variablen und Funktionen enthalten.
i.var
Die VAR -Anweisung wird verwendet, um eine oder mehrere Variablen zu deklarieren. Seine Syntax ist wie folgt:
var name_1 [= value_1] [, ..., name_n [= value_n]]
Auf das Schlüsselwort var folgt eine Liste von Variablen, die deklariert werden sollen. Jede Variable in der Liste kann einen Initialisierungsausdruck haben, mit dem der Anfangswert angegeben werden kann. Zum Beispiel:
Die Codekopie lautet wie folgt:
var i; // eine einfache Variable
var J = 0; // eine Variable mit Anfangswert
var p, q; // zwei Variablen
var greet = "Hallo" + Name; // komplexere Initialisierungsausdruck
var x = 2,34, y = math.cos (0,75), r, theta; // viele Variablen
var x = 2, y = x * x; // Die zweite Variable verwendet die erste Variable
var x = 2,
f = Funktion (x) {return x * x}, // Jede Variable hat eine Zeile exklusiv
y = f (x)
Wenn die VAR -Anweisung in der Funktionskörper angezeigt wird, definiert sie eine lokale Variable, und ihr Umfang ist diese Funktion. Wenn Sie eine VAR-Anweisung im Code der obersten Ebene verwenden, deklariert sie eine globale Variable, die im gesamten JavaScript sichtbar ist. In Kapitel 3, Abschnitt 10, wird erwähnt, dass globale Variablen Eigenschaften globaler Objekte sind. Im Gegensatz zu anderen globalen Objekteigenschaften können Variablen, die von VAR deklariert sind, nicht durch Löschen gelöscht werden.
Wenn die Variable in der VAR -Anweisung keinen Initialisierungsexpression angibt, ist der Wert dieser Variablen zunächst undefiniert. Daher ist der Wert der Variablen vor der Deklarationsanweisung undefiniert.
Es ist zu beachten, dass die VAR -Anweisung auch als Komponente der für die Schleife oder für/in der Schleife verwendet werden kann. (Gleich wie die vor Schleifen deklarierten Variablenerklärungen, die deklarierten Variablen hier ebenfalls "fortgeschritten" sind), beispielsweise:
Die Codekopie lautet wie folgt:
für (var i = 0; i <10; i ++) console.log (i);
für (var i = 0, j = 10; i <10; i ++, j--) console.log (i * j);
für (var i in o) console.log (i);
Beachten Sie, dass es keine Rolle spielt, ob Sie die gleiche Variable mehrmals deklarieren.
II. Funktion
Die Schlüsselwortfunktion wird verwendet, um Funktionen zu deklarieren. Wir haben Funktionsausdrücke gelernt (4.3). Funktionsdefinitionen können in eine Form einer Anweisung geschrieben werden. Zum Beispiel: Zwei Definitionen werden im folgenden Beispielcode geschrieben:
Die Codekopie lautet wie folgt:
var f = Funktion f (x) {return x + 1;} // zu einer Variablen den Ausdruck zuweisen
Funktion f (x) {return x + 1;} // Satz, der Variablennamen enthält
Die Syntax der Funktionserklärung lautet wie folgt:
Die Codekopie lautet wie folgt:
Funktionsfunktionsname ([arg1 [, arg2 [..., argn]]]) {
Aussagen
}
Funcname ist der Namensbezeichner der zu deklarierenden Funktion. Auf den Funktionsnamen folgt die von Kommas getrennte Parameterliste. Bei Aufrufen einer Funktion beziehen sich diese Kennungen auf die tatsächlichen Parameter, die an die Funktion übergeben wurden.
Die Funktionsstelle besteht aus JavaScript -Anweisungen, ohne die Anzahl der Anweisungen zu begrenzen und in lockige Klammern eingeschlossen ist. Bei der Definition einer Funktion werden die Anweisungen in der Funktionskörper nicht ausgeführt, sondern dem neuen Funktionsobjekt zugeordnet, das beim Aufrufen der Funktion ausgeführt werden soll. Beachten Sie, dass lockige Klammern in Funktionsfunktionsfunktionsanweisungen erforderlich sind, was sich von den Anweisungsblöcken unterscheidet, die von Schleifen und anderen Anweisungssperrungen verwendet werden. Auch wenn der Funktionskörper nur eine Anweisung hat, sind lockige Klammern dennoch erforderlich, um sie abzuschließen.
Die Codekopie lautet wie folgt:
Funktion hyteus (x, y) {
return math.sqrt (x * x + y * y);
}
Hyteus (1, 2) //=>2.23606797749979
Funktion Gesichtsbehandlung (n) {// Eine rekursive Funktion
if (n <= 1) return 1;
return n * Gesichtsbehandlung (n - 1);
}
Gesichtsbehandlung (11) // => 39916800
Funktionserklärungen erscheinen normalerweise ganz oben im JavaScript -Code und können auch innerhalb anderer Funktionen verschachtelt werden. Bei verschachtelten Funktionen können jedoch nur noch oben in der verschachtelten Funktion erscheinen. Das heißt: Die Funktionsdefinition kann nicht angezeigt werden, wenn oder andere Aussagen.
Wie bei der VAR -Anweisung können Variablen, die durch Funktionserklärungserklärungen erstellt wurden, nicht gelöscht werden. Diese Variablen sind jedoch nicht schreibgeschützt, und die Variablenwerte können neu geschrieben werden.
4. Bedingte Aussagen
Eine bedingte Anweisung besteht darin, bestimmte Aussagen auszuführen oder zu überspringen, indem festgestellt wird, ob der Wert des angegebenen Ausdrucks bewertet werden soll. Diese Aussagen sind "Entscheidungspunkte" des Code, manchmal als "Zweige" bezeichnet. Wenn der JavaScript -Interpreter nach dem "Pfad" des Codes ausgeführt wird. Die bedingte Aussage ist der Gabelpunkt auf diesem Weg. Wenn das Programm diesen Punkt erreicht, müssen Sie einen Pfad auswählen, um die Ausführung fortzusetzen.
I. wenn
Wenn Anweisung eine grundlegende Steuererklärung ist. Um genau zu sein, ermöglicht es dem Programm, bedingt auszuführen. Es gibt zwei Formen dieser Aussage: Der erste ist
Die Codekopie lautet wie folgt:
if (Ausdruck)
Stellungnahme
Wenn der Ausdruckswert wahr ist, führen Sie in dieser Form die Anweisungsanweisung aus und führen Sie die Anweisung nicht aus. Zum Beispiel,
Die Codekopie lautet wie folgt:
if (userername == null) // Wenn der Benutzername null oder undefiniert ist
Benutzername = "Jack Wong"; // es definieren
Es ist zu beachten, dass es notwendig ist, die Gartenklammern des Ausdrucks bei der Aussage beizulegen.
JavaScript -Syntax sieht vor, dass Keywords und Ausdrücke mit Gartenklammern von einer Erklärung folgen müssen. Es können jedoch mehrere Anweisungen mit Anweisungsblöcken kombiniert werden. Daher sieht die Form der IF -Aussage so aus:
Die Codekopie lautet wie folgt:
if (! Adresse) {
Adresse = "";
Message = "Bitte senden Sie die Adresse"
}
Die zweite Form der IF -Anweisung führt die elsee Klausel ein und führt die else -Logik aus, wenn der Wert des Ausdrucks falsch ist.
Die Codekopie lautet wie folgt:
if (Ausdruck)
Erklärung1
anders
Erklärung2
Zum Beispiel der folgende Code
Die Codekopie lautet wie folgt:
if (n == 1)
console.log ("1 neue Nachricht");
anders
console.log ("Sie haben" + n + "neue Nachricht");
Bei Verwendung von if/else -Anweisungen in der verschachtelten Verwendung von iF -Anweisungen müssen Sie darauf achten, dass die else -Anweisung mit der richtigen If -Anweisung übereinstimmt. Betrachten Sie den folgenden Code:
Die Codekopie lautet wie folgt:
i = j = 1;
K = 2;
if (i == j)
if (j == k)
console.log ("Ich gleich K");
anders
console.log ("i dosent gleich j"); //Fehler! !
In diesem Beispiel ist die innere Anweisung die von der äußeren IF -Anweisung erforderlichen Klauseln. Die passende Beziehung zwischen und sonst ist nicht klar (nur Eindrücke gibt einen kleinen Hinweis) und in diesem Beispiel ist der Hinweis durch Einrückung falsch, da der JavaScript -Interpreter dies so versteht.
Die Codekopie lautet wie folgt:
if (i == j) {
if (j == k)
console.log ("Ich gleich K");
anders
console.log ("i dosent gleich j");
}
Wie bei den meisten Programmiersprachen sind die IF und unter anderem die Regeln in JavaScript übereinstimmen, die sonst immer mit der Anweisung in der Nähe übereinstimmen. Um das Beispiel lesbar, leichter zu verstehen und bequemer für die Wartung und Debuggierung zu gestalten, sollten lockige Klammern verwendet werden.
Die Codekopie lautet wie folgt:
if (i == j) {
if (j == k) {
console.log ("Ich gleich K");
} else {// Crape -Klammern machen das Ergebnis des Codes klarer
console.log ("i dosent gleich j");
}
}
Viele Programmierer haben die Angewohnheit, den Körper von if und sonst Aussagen in lockigen Klammern zu schließen (genau wie in einer passenden Aussage wie eine Weile -Schleife). Selbst wenn es nur eine Aussage pro Zweigstelle gibt, kann dies das mehrdeutige Problem des Programms gerade jetzt vermeiden.
ii.else if
Die Anweisung If/sonst wählt eine der beiden Zweige aus, indem das Berechnungsergebnis eines Ausdrucks beurteilt wird. Was soll ich tun, wenn es viele Zweige im Code gibt? Eine Lösung besteht darin, die else -if -Anweisung zu verwenden. Andernfalls ist es nur eine Möglichkeit, mehrere If/sonst -Anweisungen zusammen zu schreiben.
Die Codekopie lautet wie folgt:
if (n == 1) {
// Code Block 1 ausführen
} else if (n == 2) {
// Code Block 2 ausführen
} else if (n == 3) {
// Code Block 3 ausführen
} anders {
// Die vorherigen Bedingungen sind falsch, dann wird der Codeblock 4 ausgeführt
}
Diese Art von Code hat nichts Besonderes. Es besteht aus multiplen If -Anweisungen, und jede Anweisung der Anweisung enthält eine andere If -Anweisung. Der äquivalente Syntax -Code kann unter Verwendung der verschachtelten Form von IF -Anweisungen abgeschlossen werden, aber im Vergleich dazu ist es offensichtlich, dass das Schreiben von sonst, wenn klarer und vorzuziehen ist.
iii.switch
Während der Ausführung des Programms erstellt eine IF -Anweisung einen Zweig und kann unter anderem wenn mehrere Zweige verarbeitet werden. Wenn dann alle Zweige vom Wert desselben Ausdrucks abhängen, ist sonst nicht die beste Lösung. In diesem Fall ist es eine sehr verschwenderische Praxis, die Ausdrücke wiederholt in mehreren If -Anweisungen zu berechnen.
Die Switch -Anweisung eignet sich zum Umgang mit dieser Situation. Auf dem Keyword -Switch folgt ein Ausdruck in Gartenklammern. Dann gibt es Codeblöcke, die in lockigen Klammern eingeschlossen sind.
Die Codekopie lautet wie folgt:
Switch (Ausdruck) {
Aussagen
}
Die vollständige Syntax der Switch -Anweisung ist jedoch komplizierter. Auf dem Fall folgt ein Ausdruck und ein Dickdarm. Der Fall ist einer Markup -Sprache sehr ähnlich, außer dass diese Markup -Sprache keinen Namen hat.
Es ist nur mit den folgenden Ausdrücken verbunden. Bei der Ausführung dieser Switch -Anweisung berechnet sie zuerst den Wert des Ausdrucks und stellt dann fest, ob der Ausdruck der Fallklausel dem Wert des Ausdrucks entspricht. (Das gleiche wird mit dem Operator "===" verglichen). Wenn der Fall übereinstimmt, wird der entsprechende Code ausgeführt. Wenn ein Übereinstimmungsfall nicht gefunden werden kann, wird der Codeblock in "Standard:" -Tag "ausgeführt. Wenn es kein "Standard:" -Tag gibt, überspringt Switch alle Codeblöcke.
Die Switch -Anweisung ist sehr einfach zu verwirren, und die Einführung mit Beispielen wird klarer sein. Die folgende Switch -Anweisung entspricht der Anweisung If/sonst, gerade jetzt.
Die Codekopie lautet wie folgt:
Schalter (n) {
Fall 1: // Wenn n === 1 von hier aus beginnt
// Code Block 1 ausführen
brechen;
Fall 2:
// Code Block 2 ausführen
brechen;
Fall 3:
// Code Block 3 ausführen
brechen;
Standard:
// Code Block 4 ausführen
brechen;
}
Es ist zu beachten, dass der Schlüsselwortunterbrechung am Ende jeder Fallanweisung verwendet wird. Wir werden die Break -Erklärung später vorstellen. Die Break -Anweisung kann dazu führen, dass der Interpreter aus der Switch -Anweisung oder Loop -Anweisung herausspringt. Im Switch gibt der Fall nur den Ausgangspunkt des zu ausgeführten Code an, gibt jedoch nicht den Endpunkt an. Wenn es keine Break -Anweisung gibt, beginnt die Switch -Anweisung mit der Ausführung aus dem Code am Matching Case -Tag des Ausdruckswertes und führt nachfolgende Anweisungen bis zum Ende des gesamten Switch -Code -Blocks aus. Wenn Sie in einer Funktion eine Switch -Anweisung verwenden, können Sie die Return verwenden, um die Pause zu ersetzen. Return und Break werden verwendet, um die Switch -Anweisung zu beenden, wodurch auch eine Fallanweisung daran teilnimmt, den nächsten Block der nächsten Fallanweisung weiter auszuführen.
Die folgende Aussage liegt nahe am tatsächlichen Kampf und konvertiert den Wert in eine Zeichenfolge gemäß dem Typ des Wertes.
Die Codekopie lautet wie folgt:
Funktion konvertieren (x) {
Switch (Typeof x) {
Fall 'Nummer': // Zahlen in Hexadezimal konvertieren
return X.ToString (16);
Fall 'String':
zurück '"' + x + '"'; // Geben Sie zwei Zeichenfolgen mit doppelten Zitaten zurück.
Standard: // Verwenden Sie normale Methoden, um andere Typen umzuwandeln
Rückgabe String (x);
}
}
console.log (konvertieren (100255114)) // => 5f9c58a
Beachten Sie, dass in den beiden oben genannten Beispielen auf das Schlüsselwort der Fall eine direkte Anzahl und Zeichenfolge folgt, die die häufigste Verwendung des Schalters in der Praxis ist. Mit dem ECMAScript -Standard kann jedes Schlüsselwort willkürliche Ausdrücke folgen.
Die Switch -Anweisung berechnet zunächst den Ausdruck nach dem Schlüsselwort des Switchs und dann den Ausdruck nach jedem Fall, damit von oben nach unten geeignet ist, und weiß, dass der Wert des an den Fall ausgeführten Ausdrucks und den Wert des Ausdrucks des Schalters gleich sind. Da der Matching -Operation für jeden Fall tatsächlich ein "===" -Identitätsoperatorvergleich ist, nicht "==", führt die Übereinstimmung von Ausdruck und Fall keine Typumwandlung durch.
Jedes Mal, wenn eine Switch -Anweisung ausgeführt wird, können nicht alle Fallausdrücke ausgeführt werden. Daher sollten Fallausdrücke mit Nebenwirkungen vermieden werden, wie z. B. Funktionsaufrufe Ausdrücke und Zuordnungsausdrücke. Der sicherste Weg ist die Verwendung konstanter Ausdrücke in Fallausdrücken.
Wie bereits erwähnt, wird der Anweisungsblock "Standard" ausgeführt, wenn der Switch -Ausdruck nicht mit allen Fallausdrücken übereinstimmt. Wenn es kein "Standard:" -Tag gibt, wird die gesamte Switch -Anweisung übersprungen. Im vorherigen Beispiel wird am Ende des Schalters das Tag "Standard:" Standard: "Tag" angezeigt und steht hinter allen Fall -Tags. Dies ist natürlich die vernünftigste und am häufigsten verwendete Art des Schreibens. In der Tat kann das Tag "Standard:" Tag in der Switch -Anweisung überall platziert werden.
5. Schleife.
Um die bedingten Aussagen zu verstehen, können Sie den Code in JavaScript als Zweigpfade vorstellen. Looping -Anweisungen sind Schleifenanweisungen, mit denen ein Code wiederholt ausgeführt wird. JavaScript gibt es vier Schleifenanweisungen: während, während, während, für und für/in. In den folgenden Abschnitten werden sie gleichzeitig erläutert. Die am häufigsten verwendete Schleife ist der Durchqueren von Array -Elementen. (7.6 werden diese Schleifen- und Spezialschleifenmethoden im Detail erörtert.)
I. Mit
Wenn eine Anweisung eine grundlegende Steuererklärung ist, die zur Auswahl von Zweiganweisungen verwendet wird, die das Programm ausführen. Wie wenn, ist die Anweisung auch eine grundlegende Schleifenanweisung, und ihre Syntax lautet wie folgt:
Die Codekopie lautet wie folgt:
Während (Ausdruck)
Stellungnahme
Vor der Ausführung einer Weile -Anweisung berechnet der JavaScript -Interpreter zunächst den Wert des Ausdrucks. Wenn sein Wert ein falscher Wert ist, überspringt das Programm die logische Anweisung im Schleifenkörper und führt die nächste Anweisung im Programm aus. Wenn sein Wert wahr ist, wird die Logik in der Schleifenkörperanweisung ausgeführt, und dann wird der Wert des Expressionsausdrucks berechnet. Die Schleife wird fortgesetzt, bis der Wert des Ausdrucks falsch ist. Mit anderen Worten, wenn der Ausdruck wahr ist, wird die Anweisung in einer Schleife ausgeführt. Beachten Sie, dass die Verwendung von while (true) eine tote Schleife erstellt.
Im Allgemeinen möchten wir nicht, dass JavaScript dieselbe Operation wiederholt ausführt. In fast jeder Schleife ändert sich eine oder mehrere Variablen iterativ mit der Schleife. Gerade weil diese Variablen geändert werden, sind die in jeder Schleife durchgeführten Anweisungsvorgänge unterschiedlich. Wenn das Ändern der Variablen in der Expression verwendet wird, ist außerdem der Wert der Expression jeder Schleife unterschiedlich. Das ist sehr wichtig. Der Ausdruck, der für den Anfangswert des wahren Wertes verantwortlich ist, ist immer der wahre Wert, und die Schleife endet nicht. Das folgende Beispiel zeigt, dass die Schleife die Werte 0-9 ausgibt.
Die Codekopie lautet wie folgt:
var count = 0;
while (count <10) {
console.log (count);
zählen ++;
}
Es ist festzustellen, dass in diesem Beispiel der Anfangswert der variablen Anzahl 0 beträgt, und während der Schleife wird der Wert jedes Mal um 1 erhöht, wenn die Schleife zehnmal ausgeführt wird. Der Wert des Ausdrucks ist falsch programmiert, und während der Beendigung wird, und der JavaScript -Interpreter wird die nächste Aussage des Programms ausführen. Die meisten Schleifen haben eine Gegenvariable wie Count. Obwohl Zähler häufig Variablennamen wie IJK verwenden, sollten Sie spezifischere Syntaxnamen verwenden, wenn Sie den Code lesbarer gestalten möchten.
ii.do/Win
Die Do/während der Schleife ist der while -Schleife sehr ähnlich, außer dass er den Schleifenausdruck am Schwanz der Schleife und nicht oben erkennt, was bedeutet, dass der Schleifenkörper mindestens einmal ausgeführt wird. Die Syntax der DO/während der Schleife lautet wie folgt:
Die Codekopie lautet wie folgt:
Tun
Stellungnahme
während (Ausdruck);
DO/während Schleifen nicht so häufig verwendet werden wie während der Schleifen. Dies liegt daran, dass es in der Praxis nicht üblich ist, mindestens einmal Schleifen auszuführen. Hier ist ein Beispiel für eine Do/while -Schleife
Die Codekopie lautet wie folgt:
Funktion printArray (a) {
var len = a.länge,
i = 0;
if (len == 0)
console.log ("leeres Array");
anders
Tun {
console.log (a [i]);
} while (++ i <len);
}
printArray ([1,5,2,6])
Es gibt zwei Syntaxunterschiede zwischen DO/während Schleifen und normalen Schleifen. Zunächst verlangt die DO -Schleife, dass das Schlüsselwort DO verwendet werden muss, um den Beginn der Schleife zu identifizieren, während die Variable das Ende der Schleife identifiziert und die Schleifenbedingung eingeben, um sie zu beurteilen. Zweitens verwendet die DO -Schleife im Gegensatz zur while Loop ein Semikolonende. Wenn der Körperschleifenkörper in lockige Klammern eingeschlossen ist, endet die WHOR -Schleife nicht mit einem Semikolon.
iii.for
Die For -for -Erklärung bietet eine bequemere Schleifenstruktur als während der Zeit. Die für die Anweisung vereinfacht den häufig verwendeten Schleifenmodus. Die meisten Schleifen haben spezifische Gegenvariablen. Diese Variable wird vor Beginn der Schleife initialisiert und überprüft dann ihren Wert vor jeder Schleife. Schließlich ist die Zählervariable selbst imkrementiert, ansonsten wird sie nach Ablauf des Zyklus und vor dem nächsten Urteil geändert. In dieser Art von Schleife sind die drei Schlüsselvorgänge des Zählers Initialisierung, Erkennung und Aktualisierung. Die für die Aussage ausdrücklich deklariert diese drei Operationen als Teil der Schleifensyntax, die jeweils einen Ausdruck verwenden, um sie darzustellen. Die Syntax der für die Aussage lautet wie folgt:
Die Codekopie lautet wie folgt:
für (initialisieren; testen; Inkrement)
Stellungnahme
Die drei Ausdrücke von Initialisierung, Test und Inkrement werden durch Semikolonen getrennt. Sie sind für die Initialisierung von Operationen, das Beurteilung des Zyklischen Zustands und die Aktualisierung der Zählervariablen verantwortlich. Wenn Sie sie in die erste Zeile der Schleife setzen, wird es einfacher zu verstehen, was die für die Schleife tut, und verhindert auch das Vergessen, die Zählervariable zu initialisieren oder zu erhöhen.
Der einfachste Weg zu erklären, wie A for Loop funktioniert, besteht darin, ein Äquivalent während der Schleife aufzulisten
Die Codekopie lautet wie folgt:
initialisieren
while (test) {
Stellungnahme
Inkrement;
}
Mit anderen Worten, der Initialisierungsausdruck wird nur einmal vor Beginn der Schleife ausgeführt. Der Initialisierungsausdruck sollte Nebenwirkungen haben (normalerweise eine Zuordnungsanweisung). JavaScript ermöglicht auch Initialisierungsausdrücke mit VAR -Variablen -Deklarations -Anweisungen, sodass eine Variable deklariert und initialisiert werden kann. Vor jeder Schleife wird der Testausdruck ausgeführt und das Ergebnis des Ausdrucks wird beurteilt, ob die Schleifenkörper ausgeführt werden sollen. Vor jeder Schleife wird der Testausdruck ausgeführt und das Ergebnis wird festgelegt, ob die Schleifekörper ausgeführt wird. Wenn das Testergebnis der wahre Wert ist, wird die Anweisung im Schleifenkörper ausgeführt. Führen Sie schließlich den Inkrementausdruck aus. Auch aus Gründen der Nützlichkeit muss der Inkrementausdruck hier auch Nebenwirkungen haben. Im Allgemeinen handelt es sich entweder um einen Zuweisungsausdruck oder einen Ausdruck, der aus "++" und "-"-"Operatoren besteht.
Die obige während der Schleife kann mit einer für die Schleife geschrieben werden
Die Codekopie lautet wie folgt:
für (var count = 0; count <10; count ++)
console.log (count)
Natürlich sind einige Schleifen komplexer und mehrere Variablen werden gleichzeitig in der Schleife iteriert. In JavaScript muss dieser Fall mit einem Komma -Operator verwendet werden, der den Initialisierungsausdruck und den automatischen Ausdruck in einem Ausdruck für die Verwendung in A for Loop kombiniert.
Die Codekopie lautet wie folgt:
var i, j;
für (i = 0, j = 10; i <10; i ++, j-)
console.log (i * j);
Bisher sind die Schleifenvariablen im Beispielcode alle Zahlen. Natürlich werden Zahlen die am häufigsten verwendeten, aber nicht notwendig. Der folgende Code verwendet eine für Schleife, um die Tabellendatenergebnisse zu durchqueren und das letzte Objekt in der verlinkten Liste zurückzugeben (dh das erste Objekt, das nicht das nächste Attribut enthält).
Die Codekopie lautet wie folgt:
Funktion Tail (o) {// Gibt das letzte Knotenobjekt der verknüpften Liste zurück
für (; O.Next; o = O.Next) /*leer*// Durchquerung durchführen, basierend darauf, ob O.Next der wahre Wert ist
Rückkehr O;
}
Es ist zu beachten, dass dieser Code keine Initialisierungsausdrücke enthält und Personen und einer der drei Ausdrücke in der für Schleife ignoriert werden können, aber zwei Semikolonen sind unverzichtbar. Wenn der Testausdruck weggelassen wird, wird es eine tote Schleife sein. Auch mit dem Typ (ture) ist eine Möglichkeit, eine tote Schleife zu schreiben, für (;;).
iiii.for/in
Die für/in Anweisung verwendet das für Schlüsselwort, aber es ist eine andere Art von Schleife als die reguläre für die Schleife. Die Syntax der for/in Loop ist wie folgt
Die Codekopie lautet wie folgt:
für (Variable im Objekt)
Stellungnahme
Eine Variable ist normalerweise ein variabler Name oder ein Ausdruck, der Lvalues erzeugen kann, oder eine Variable, die durch eine VAR -Anweisung deklariert wird. Wie auch immer, es ist ein Wert, der auf der linken Seite des Zuweisungsausdrucks gilt. Objekt ist ein Ausdruck, und das Ergebnis dieses Ausdrucks ist ein Objekt. In ähnlicher Weise ist eine Aussage oder eine Aussage oder ein Aussagen, die den Körper der Schleife bilden.
Es ist sehr einfach, eine für die Schleife durch Array -Elemente zu verwenden, um durch Array -Elemente zu iterieren
Die Codekopie lautet wie folgt:
var a = [1, 3, 5, "44"];
für (var i = 0; i <A.Length; i ++) // I repräsentiert den Index der Array -Elemente
console.log (a [i]) // Ausgabeelemente jedes Arrays Ausgabe
Die für/in der Schleife wird verwendet, um die Eigenschaften der Objektelemente bequem zu durchqueren
Die Codekopie lautet wie folgt:
für (var p in o) // dem Namen des Attributs der Variablen p zuweisen
console.log (o [p]); // Ausgabe des Wertes jedes Attributs ausgeben
Bei der Ausführung der For/In -Anweisung berechnet der JavaScript -Interpreter zunächst den Objektausdruck. Wenn der Ausdruck null oder undefiniert ist, überspringt der JavaScript -Interpreter die Schleife und führt den nachfolgenden Code aus. Wenn der Ausdruck einem primitiven Wert gleich ist, wird dieser primitive Wert in das Wrapper -Objekt konvertiert (Abschnitt 3.6). Andernfalls ist der Ausdruck selbst bereits ein Objekt. JavaScript zählt die Eigenschaften des Objekts wiederum auf, um die Schleife auszuführen. Vor jeder Schleife berechnet JavaScript jedoch den Wert des variablen Ausdrucks und weist ihm den Attributnamen (eine Zeichenfolge) zu.
Es ist zu beachten, dass der Wert von Varibale so lange wie der für/in der Schleife als LVALUE des Zuweisungsausdrucks angesehen werden kann, und es kann jeder Ausdruck sein. Dieser Ausdruck wird bei jeder Schleife berechnet, was bedeutet, dass der von ihm berechnete Wert bei jedem Schleifen unterschiedlich sein kann. Beispielsweise können Sie den folgenden Code verwenden, um alle Objekteigenschaften in ein Array zu kopieren:
Die Codekopie lautet wie folgt:
var o = {x: 1, y: 2, z: 3};
var a = [], i = 0;
für (a [i ++] in o) /*leer* /;
document.write (a) // => x, y, z
JavaScript -Arrays sind nur ein spezielles Objekt, sodass die für/in der Schleife Datenindizes wie die Aufzählungsobjekteigenschaften aufzählen kann. Zum Beispiel kann das Hinzufügen dieses Codes nach dem obigen Code den Datenindex 0, 1, 2 aufzählen:
Die Codekopie lautet wie folgt:
var o = {x: 1, y: 2, z: 3};
var a = [], i = 0;
für (a [i ++] in o) /*leer* /;
document.write (a) // => x, y, z -Objekteigenschaften in ein Array kopieren
für (ich in a)
document.write (i) // => Enum -Datenindex 0 1 2
Tatsächlich durchquert die für/in Schleife nicht alle Eigenschaften des Objekts. Nur die "aufzählbaren" Attribute werden überquert (siehe 6.7). Da die vom JavaScript-Sprachkern definierten integrierten Methoden nicht "aufgezählt" sind. Beispielsweise haben alle Objekte toString (), aber die für/in Schleife zählt die Eigenschaft nicht auf, tostring () zu zählen. Zusätzlich zu integrierten Methoden gibt es viele integrierte Objekte, die nicht aufgezählt werden können. Alle im Code definierten Attribute und Methoden sind aufgezählt (Abschnitt 6.7 werden erwähnt, es gibt jedoch spezielle Mittel in ECMAScript5, die Attribute nicht aufzählbar machen können).
Objekte können die Eigenschaften anderer Objekte erben, und die Linie erbt benutzerdefinierte Eigenschaften (6.2.ii) können auch mit für/in aufgezählt werden.
Wenn die für/in der Schleifenkörper eine nicht engere Eigenschaft löscht, wird diese Eigenschaft nicht erneut aufgezählt. Wenn die Schleifenkörper neue Eigenschaften des Objekts definiert, werden diese Eigenschaften normalerweise nicht aufgezählt (einige Implementierungen von JavaScript können die im Schleifenkörper hinzugefügten Eigenschaften aufgezählt).
Die Reihenfolge der Attributaufzählung
In der ECMascript -Spezifikation wird nicht angegeben, in welcher Reihenfolge die For/in Loop die Eigenschaften des Objekts aufgeschrieben wird. Tatsächlich zählt der Mainstream -Browserhersteller JavaScript -Implementierung die Eigenschaften einfacher Objekte in der Reihenfolge der Attributdefinitionen auf, und die zuerst definierten Eigenschaften werden zuerst aufgezählt. Wenn ein Objekt in Form einer direkten Menge erstellt wird, wird es in der Reihenfolge aufgezählt, in der die Eigenschaften in der direkten Menge erscheinen. (Einige Netzwerk- und JavaScript -Bibliotheken verlassen sich auf diese Aufzählungsreihenfolge, während die Browserhersteller diese Reihenfolge meistens nicht ändern.) In den folgenden Fällen hängt die Aufzählungsreihenfolge von der spezifischen Implementierung ab (nicht von Interaktion)
1. Objekte erben auflistierbare Attribute
2. Objekt hat Eigenschaften des Integer -Array -Index
3.. Verwenden Sie Löschen, um die vorhandenen Eigenschaften des Objekts zu löschen
4. Verwenden Sie Object.DefineProperty () oder ähnliche Methoden, um die Objekteigenschaften zu ändern
6. Sprung
In JavaScript ist eine Art Anweisung eine Sprunganweisung. Aus einem Aussageverständnis kann die Ausführung von JavaScript von einer Position zu einer Position springen.
Die Break -Aussage besteht darin, bis zum Ende einer Schleife oder einer anderen Aussage zu springen. Die Fortsetzung der Anweisung beendet die Ausführung dieser Schleife und startet die Ausführung der nächsten Schleife. Aussagen in JavaScript können benannt oder gekennzeichnet sein, brechen und fortsetzen können Zielschleifen oder andere Anweisungs -Tags identifizieren.
Mit der Return -Anweisung ermöglicht es dem Interpreter, aus der Ausführung des Funktionsorganisation herauszukommen. Und geben Sie den Rückgabewert dieses Anrufs an. Die Throw -Anweisung löst oder löst eine Ausnahme aus, die mit der Anweisung Try/Catch/Schlussfolgerung verwendet wird, wodurch die Code -Logik für die Ausnahmebehandlung angegeben ist. Dies ist eine komplexe Sprungerklärung. Wenn eine Ausnahme ausgelöst wird, springt das Programm zum nächsten Star für geschlossene Ausnahme. Dieses Ausnahmeprogramm kann in derselben Funktion oder im Anrufstapel auf einer höheren Ebene sein.
Beschreiben Sie als nächstes jede Sprunganweisung
ich. Tag -Anweisung
Eine Erklärung kann gekennzeichnet werden und das Etikett besteht aus der Kennung und Dickdarm vor der Aussage:
Kennung: Aussage
Durch das Definieren eines Tags für eine Anweisung können Sie diese Anweisung mit ihrem Tag -Namen überall im Programm beziehen. Sie können Beschriftungen für mehrere Anweisungen definieren, obwohl dies nur bei der Definition von Beschriftungen für Anweisungsblöcke wie Schleifenanweisungen oder bedingte Beurteilungsanweisungen ist. Indem Sie einen Tag -Namen für die Schleife definieren, können Sie Break verwenden und in der Schleifenkörper fortfahren, um die Schleife zu verlassen oder direkt zum Beginn der nächsten Schleife herauszufordern. break and continue are the only statements in JavaScript that can use statement tags (this chapter will be discussed next). The following example, where the while loop defines a tag, and the continue statement uses this tag:
Die Codekopie lautet wie folgt:
mainloop: while (token != null) {
//忽略这里代码...
continue mainloop; //跳转到下一次循环
//忽略这里的代码...
}
这里做标签的indentifier必须是一个合法的javascript标识符,而不能是一个保留字。标签的命名空间和变量或函数的命名空间是不同的,因此可以使用同一个标识符作为语句标签和作为变量名或函数名。语句标签只在它所起作用的语句(当然可以在它的子句)内是有定义的。一个语句标签不能和它内部的语句标签重名,但在两个代码不相互嵌套的情况下是可以出现同名语句标签的。带有标签的语句还可以带有标签,也就是说,任何语句可以有很多个标签。
ii.break
单独使用break语句的作用是立即退出最内存的循环或switch语句。它的语法如下:
brechen;
由于它能够使循环和switch语句退出,因此这种形式的break只能出现在这类语句中才是合法的。
我们在switch语句的例子中已经见到果break语句。在循环中,无论出于什么原因,只要不想继续执行整个循环,就可以用break提前退出。当循环终止条件非常复杂时,要函数体内使用break语句实现这样些条件判断的做法要比直接在循环表达式中写出这个复杂的终止条件做法简单的多。
下面的例子中循环遍历整个数组元素来查找某个特定的值,当整个数组遍历完成后正常退出循环,如果找到了需要查找的数组元素,则使用break语句退出循环:
Die Codekopie lautet wie folgt:
for (var i = 0; i < a.length; i++) {
if (a[i] == target) break;
}
javascript中同样允许break关键字后跟随一个语句标签,(只有标识符,没有冒号)
Break LabelName;
当break和标签一块使用时,程序将跳转到这个标签所识别的语句块的结束,或者直接终止这个闭合语句块的执行。当没有任何闭合语句块指定break所用的标签,这时会产生一个语法错误。当使用这种形式的break语句时,带标签的语句不应该是循环或者switch语句,因为break语句可以“跳出”任何闭合的语句块。这里的语句可以是由花括号组起来的一组语句,使用同一个标签来识别一组语句。
break关键字和labelname之间不能换行。因为javascript可以给语句自动补全省略掉的分号,如果break关键字和标签之间有换行,javascript解释器会认为你在使用break不带标签的最简形式,因此会在break后补充分号.
当你希望通过break来跳出非就近的循环体或者switch语句时,就会用到带标签的break语句。下面是示例代码:
Die Codekopie lautet wie folgt:
var matrix = getData(); //从某处获得一个二维数组
//将矩阵中所有元素进行求和
var sum = 0,
success = false;
//从签名处开始,以便在报错时推出程序。
compure_sum: if (matrix) {
for (var x = 0; x < matrix.length; x++) {
var row = matrix[x];
if (!row) break compure_sum;
for (var y = 0; y < row.length; y++) {
var cell = row[y];
if (isNaN(cell)) break compure_sum;
sum += cell;
}
}
success = true;
}
//break语句跳转至此
//如果success =false条件到达这里,说明我们给出的矩阵中有错误
//否则对矩阵中所有的元素进行求和
最后,需要注意的是,不管break语句带不带标签,它的控制权都无法越过函数的边界。比如:对于一条带标签的函数定义语句来说,不能通过函数内部通过这个标签来跳转到函数外部.
iii.continue语句
continue语句和break语句非常类似,但它不退出循环,而是转而执行下一次循环。continue语句的语法和break的语句语法一样简单
weitermachen;
continue语句会也会带有标签
continue lebname;
不管continue语句带不带标签,它只能在循环体使用,在其它地方使用将会报语法错误。
当执行到continue语句的时候,当前的循环逻辑就终止了,随即执行下一次循环,在不同类型的循环中,continue的行为也有区别
1.在while循环中,在循环开始处指定expression会重复检测,如果检测结果为true,循环体会从头执行。
2.在do/while循环中,程序的执行至今跳转到循环的结尾处,这时会重新判断循环条件,之后才会继续下一次循环。
3.在for循环中,首先会计算自增表达式,然后再检测test表达式,用以判断是否执行循环体。
4.在for/in循环中,循环开始遍历下一个属性名,这个属性名赋给了指定的变量。
需要注意continue语句在while和for循环中的区别,while循环直接进入下一轮的循环条件判断,但for循环首先计算器increment表达式,然后判断循环条件。之前的章节讨论了和while循环“等价”的for循环行为。但由于continue在这两种循环中行为表现不同,因此使用while循环不可能完美的模拟等价的for循环。
下面这段代码展示了不带标签的continue语句,产生一个错误的时候跳过当前循环的后续逻辑
Die Codekopie lautet wie folgt:
for (i = 0; i < data.length; i++) {
if (!data[i]) continue; //不能处理undefined数据
total += data[i];
}
和break语句类似,带标签的continue语句可以用在嵌套的循环中,用以跳出层次嵌套的循环体逻辑。同样和break语句类似,在continue语句和labname之间不能有换行。
iiii.return
回想一下,函数调用的一种表达式,而且所有的表达式都有值。函数中的return语句即是指函数调用后的返回值。这里是return语句的语法:
return expression;
The return statement can only appear in the function body. If not, it will report a syntax error. When the return statement is executed, the function terminates the execution and returns the value of the expression to the calling program. Zum Beispiel:
Die Codekopie lautet wie folgt:
function square(x) {return x * x} //一个包含return的语句函数
square(4) //执行为16
如果没有return语句,则函数调用仅依次执行函数体内的每一条语句直到函数结束,最后返回调用程序。这种情况下,调用表达式的结果是undefined。return语句经常作为函数内最后的一条语句出现,但并不是说一定一定要放在函数的最后,即使在执行return语句的时候还有很多代码没有执行到,这时候函数也还返回调用程序。
The return statement can be used alone without having expression, so the function will also want to call the program to return undefined. Zum Beispiel:
Die Codekopie lautet wie folgt:
//如果参数是null或者undefined则立即返回
if (!o) return;
//其它逻辑
由于javascript可以自动插入分号,因此,return关键字和它后面的表达式之间不能有换行。
iiiii.throw语句
所谓异常(excepion)是当发生了某种异常情况或错误时产生的一个信号。抛出异常,就是用信号通知发生了错误或异常状况。捕获异常是指处理这个信号,抛出异常,就是用信号通知发生了错误或异常状况。捕获异常是指处理这个信号,即采取必要的手段从异常中汇丰。在javascript中,当产生运行时错误或者程序使用throw语句时就会显式的抛出异常。使用try/catch/finally语句可以捕获异常,下一节会对它作详细介绍。
throw语句的语法如下:
throw expression
expression的值可以是任意类型的。可以抛出一个代表错误码的数组,或者包含可错误消息的字符串。当javascript解释器抛出异常的时候,通常采用Eeeor类型或其子类型,当然也可以使用它们。一个error对象有一个那么熟悉表示错误类型,一个message属性用来传递构造函数的字符串(参照第三部分的Error类),在下面的例子中,当使用非法参数调用函数时就抛出一个Error对象:
Die Codekopie lautet wie folgt:
function fa(x) {
//如果输入的参数是非法的,则抛出一个异常
if (x < 0) throw new Error("x不能是负数。");
//否则计算出一个值,正常地返回它
for (var f = 1; x > 1; f *= x, x--) /*empty*/;
return f;
}
当抛出异常时,javascript解释器会立即停止当前正在执行的逻辑,并跳转至就近的异常处理程序。异常处理程序用try/catch/finally语句的catch从句编写的。如果抛出的异常没有一条关联catch从句,解释器会检测更高层的闭合代码块,看它是否关联相关的异常处理程序。以此类推,直到扎到一个异常处理的程序为止。
如果抛出的异常函数没有处理它的try/catch/finally语句,异常将向上传播到调用该函数的代码。这样的话,异常就会沿着javascript方法的词法结构和调用栈向上传播。如果没有找到任何异常处理的程序,javascript将吧异常当成程序错误来处理,并报告给用户。
iiiiii.try/catch/finally语句
try/catch/finally语句是javascript的异常处理机制。其中try从句定义了需要处理的异常所在代码块。catch语句跟随在try从句之后,当try块从某处发送了异常时,调用了catch内的代码逻辑。catch从句跟随finnlly块,后者防置了清理代码,不管try块中是否产生了异常,finnally块内的逻辑总会执行。尽管catch和finally都是可选的,但try从句只杀二者之一与组成完整的语句。try、catch和finally语句块都需要花括号括起来,这里的花括号是必须的。即使从句中只有一条语句也不能省略花括号。
下面的代码说明了try/catch/finlly的语法和使用目的:
Die Codekopie lautet wie folgt:
versuchen{
//通常来讲,这里的代码会从头执行到尾而不会产生任何问题,
//但有时会抛出一个异常,要么是由throw语句直接抛出异常
//要么通过调用一个方法间接抛出异常
}
catch(e){
//当且仅当try抛出了异常,才会执行这里的代码
//这里可以通过局部变量e来获得对Error对象或者抛出的其它值的引用
//这里的代码可以基于某种原因处理这个异常,也可以忽略这个异常。
//还可以通过throw语句重新抛出异常
}
Endlich{
//不管try语句块是否抛出看异常,这里的逻辑总会执行,终止try的语句块方式有:
//1)正常终止,执行完语句块的最后一条语句
//2)通过break,continue或return语句终止
//3)抛出一个异常,异常被catch从句捕获
//4)抛出一个异常,异常未被捕获,继续向上传播
}
我们注意到,关键字catch后跟随了一对圆括号,圆括号内是一个标识符。这个标识符和函数参很像。当捕获一个异常时,把这个异常相关的值(比如Error对象)赋值给这个参数。和普通的变量不同,这条catch子句中的标识符具有块级作用域,它只在catch语句块内有定义。
这里有一个关于try/catch语句更实际的例子,这里使用了前面章节中提到factorial()方法,并使用客户端javascript方法prompt()和alert()来输入和输出
Die Codekopie lautet wie folgt:
versuchen {
//要求用户输入一个数字
var n = Number(prompt("请输入一个正整数", ""));
//假设输入是合法的,计算这个阶乘
var f = factorial(n);
//显示结果
alert(n + "!=" + f);
} catch (ex) {
//如果输入不合法,将执行这里的逻辑
document.write(ex); //告诉用户发送了什么。
}
这里的try/catch语句并不包含finally从句。尽管finally不像catch那样经常使用,但有时候它还是非常有用。然而,我们需要更详尽的解释它的行为。不管try语句块中的代码执行完成了多少,只要try语句中有一部分代码执行了,finally从句就会执行。它通常在try从句的代码后用于清理工作。
关注下面这个例子
Die Codekopie lautet wie folgt:
versuchen {
print("Outer try running..");
versuchen {
print("Nested try running...");
throw "an error";
} catch (e) {
print("Nested catch caught " + e);
throw e + " re-thrown";
} Endlich {
print("Nested finally is running...");
}
} catch (e) {
print("Outer catch caught " + e);
} Endlich {
print("Outer finally running");
}
// Windows Script Host 作出该修改从而得出WScript.Echo(s)
function print(s) {
document.write(s);
}
Ausgabe:
Die Codekopie lautet wie folgt:
Outer try running..
Nested try running...
Nested catch caught an error
Nested finally is running...
Outer catch caught an error re-thrown
Outer finally running
7.其它语句类型。
本节讨论剩余的三种javascript语句:width,debugger和use strict
i.with语句
3.10讨论了作用域链(scope chain),一个可以按序检索的对象列表,通过它可以进行变量名的解析。width语句可以用来临时扩展作用域链:它具体有如下语法:
with (object)
Stellungnahme
这条语句将object添加到作用域链头部,然后执行statement,最后把作用域链恢复到原始状态。
在严格模式下(5.7.iii)是禁止使用width的,在非严格模式下也是不推荐使用width语句的,尽可能的避免使用width语句。那些使用width语句的javascript非常难优化,而且比没有使用width的语句,它运行速度更慢。
在对象嵌套层次很深的时候,常会使用with语句来简化代码的编写。例如客户端javascript中,可能使用下面的这种表达式来访问表单的一个html元素
document.forms[0].address.value
如果这段代码多次出现,则可以使用with将form对象添加至作用域链的顶层。
Die Codekopie lautet wie folgt:
with(document.forms[0]){
//直接访问表单元素
name.value="";
address.value="";
email.value ="";
}
这种方法简化了大量的输入,不用再为每个变量添加document.forms[0]前缀。这个临时对象挂载在作用域链上,当javascript需要解析诸如address标识符时,就会在这个对象中查找。当然,不使用with的语句代码可以写成这样。
Die Codekopie lautet wie folgt:
var f = document.forms[0];
f.name.value = "";
f.adress.value = "";
f.email.value = "";
不要忘记,只有在查找标识符的时候才能用到作用域链,创建新的变量时候不使用它,看一下下面的代码:
Die Codekopie lautet wie folgt:
with(o) x = 1;
如果对象o有一个属性x,那么这行代码给这个属性赋值1。如果o没有定义属性x,这段代码和不使用with的代码x=1是一模一样的。它给一个局部变量或者全局变量x赋值,或者创建全局对象的一个新属性。with语句提供了一种读取o属性的快捷方法,但并不会创建o的属性。
ii.debugger语句
debugger语句通常什么也不做。然而,在调试程序可用并运行的时候,javascript解释器将会(非必须)以调试模式运行。实际上,这条语句产生一个断点(breakpoint),javascript代码执行会停止在断点的位置,这时可用使用调速器输出变量的值,检查调用栈等。
例如加上调用函数f()的时候使用了未定义的参数,因此f()抛出一个异常,但无法定位到到底哪里出了异常。为了有助于调试这个问题,需要修改f():
Die Codekopie lautet wie folgt:
function f(o){
if (o === undefined) debugger; //这段代码用来临时调试
console.log(1) //函数的其它部分
}
F();
这时候,当调用f()没有传入参数,程序将停止执行,这时候通过调用调速器检测调用栈并找出错误的原因。
在ECMAScirpt5中,debugger语句已经正式加入到专门语言里,但在很长的一段时间里,主浏览器的厂商已经将其实现了。注意,可用的调速器是远远不够的,debugger语句不会启动调试器。但如果调试器已经在运行,这条语句才会正在产生断点。例如,使用Firefox插件firebug,首先启动firebug,这样debugger语句才能工作。
iii.“use strict”
“use strict”是ECMASCript5引入的一条指令。指令不是语句(但非常接近于语句),“use strict”和普通语句之前有两个重要区别:
1.它不包含任何语言的关键字,指令仅仅是一个包含一个特殊字符串直接量的表达式(可以是使用单引号也可以是双引号)。
2.它只能出现在脚本代码的开始或者函数体的开始、任何实体语句之前。但它不必一定出现在脚本的首行或者函数体内的首行。因为“use strict”指令之前之后或之前都可能有其它字符串直接量的表达式语句,并且javascript的具体实现可能将它们解析为解释器自有的指令。在脚本或者函数体内第一条常规语句之后,字符串直接量表达式语句只当做普通的表达式语句对待,它们不做指令解析,它们也没有任何副作用。
使用“use strict”指令的目的是说明(脚本或函数中)后续代码解析为严格代码(strict code)。如果顶层(不在任何函数内)代码使用了“use strict”指令,那么它们就是严格代码。如果函数体定义处的代码是严格代码或者函数体使用了“use strict”指令,那么函数体的代码也是严格代码。如果eval()调用所处的代码是严格代码或者eval()要执行的字符串使用了“scrict code”指令,则eval()内的代码是严格代码。
严格代码以严格模式执行。ECMAScript5中的严格模式是该语言的一个受限的子集。它修正了语言的重要缺陷,并提供健壮的差错功能和增强安全机制。严格模式和非严格模式区别如下(前三条尤其重要)
•严格模式中禁止使用with语句
•严格模式中,所有的变量要先声明,如果给一个未声明的变量、函数、函数参数、catch从句参数或全局的对象的属性赋值。就会抛出一个引用错误异常(在非严格模式中,这种隐式声明全局变量的方法是给全局变量新添加一个新属性)
•严格模式中,调用的函数(不是方法)中的一个this值是undefined。(在非严格模式中,调用的函数中的this值总是全局变量)。可以利用这种特性来判断javascript实现是否支持严格模式。
Die Codekopie lautet wie folgt:
var hasStrictMode = (function() {
"use strict";
return this === undefined
}());
•同样,在严格模式中,当通过call()和apply()来调用函数时,其中的this值就是通过call()或apply()传第一个参数(在非严格模式中,null和undefined值被全局对象转换为对象的非对象值锁代替)
•在严格模式中,给只读属性赋值和给不可扩展的对象创建成员都将抛出一个类型错误异常(在非严格模式中,这些操作只是简单的操作失败,不会报错)。
•在严格模式中,传入eval()代码不能再调用辰星所在的上下文中声明变量或定义函数,在非严格模式中是可以这样做的。相反,变量和函数的定义是在eval()创建的作用域中,这个作用域在eval()返回时就弃用了。
•在严格模式中,函数里的arguments对象拥有传入函数值的静态副本。在非严格模式中,agreements对象具有“魔术般”的行为,arguments里的数组元素和函数都指向同一个值的引用。
•在严格模式中,当delete运算符后面跟随非法的标识符(比如变量、函数、函数参数时)将会抛出一个语法错误,(在非严格模式下,这种delete什么也没做,并返回false)
•在严格模式中,在一对象直接量中定义两个或多个同名属性将产生一个语法错误(非严格模式下不会报错)
•在严格模式下,不允许八进制整数直接量。(以0为前缀,而不是0x为前缀)在非严格模式中是允许直接八进制直接量的
•在严格模式下,标识符eval和arguments当做关键字,他们的值是不能更改的。不能给这些标识符赋值,也不能把它们声望为变量,用做函数名,用做函数参数或用做catch块的标识符。
•在严格模式中限制了对调用栈的检测能力,在严格的模式的函数中,arguments,caller和arguments.callee都会抛出一个类型错误异常。严格模式的函数同样具有caller和arguments属性,当访问这两个属性时抛出类型错误异常。
8.javascript语句小结:
javascript语句语法:
| Stellungnahme | Grammatik | verwenden |
| brechen | break[label]; | 退出最内侧循环或者退出switch语句,又或退出label指定的语句 |
| Fall | case expression: | 在switch语句标记一条语句 |
| continue | continue [label]; | 重新开始最内层的循环或从新开始label指定的循环 |
| debugger | debugger; | 断点器调试 |
| Standard | Standard; | 在switch标记默认语句 |
| do/while | do statement while(expression); | while循环的一种替代形式 |
| leer | ; | Tu nichts |
| für | for(init;test;incr)statement | 一种简写的循环 |
| for/in | for(var in object)statement | 遍历一个对象属性 |
| Funktion | function name([param[],...]){body} | 声明一个函数 |
| if/else | if (expr)statement1[else statement2] | 执行statement1或者statement2 |
| Etikett | label:statement | 给statement指定一个名字:label |
| Zurückkehren | return [expression]; | 从函数返回一个值 |
| schalten | switch(expression){statements} | 用case或者“default:”语句标记多个分支语句 |
| werfen | throw expression | 抛出异常 |
| versuchen | try {statements} [catch {hander satements}] [finally {cleanup satements}] | 捕获异常 |
| use strict | "use strict" | 对脚本和函数使用严格模式 |
| var | avr name=[=expr][,...] | 声明并初始化一个或多个变量 |
| Während | while (expression) statement | 基本的循环结构 |
| mit | with(object) statement | 扩展作用域链(不赞成使用) |