Ein Ausdruck ist eine Phrase in JavaScript, und der JavaScript -Interpreter berechnet ein Ergebnis. Häufig verwendete Mengen in Programmen sind die einfachste Art von Ausdrücken, die Variablen sind. Variablennamen sind ebenfalls ein einfacher Ausdruck, und ihr Wert ist der Wert, der der Variablen zugewiesen wird.
Komplexe Ausdrücke bestehen aus einfachen Ausdrücken. Beispielsweise besteht ein Array -Zugriffsausdruck aus einem Ausdruck, der ein Array, quadratische Klammern und einen ganzzahligen Ausdruck darstellt. Die neue Ausdrucksoperation, die sie bilden, ist der Elementwert an einer bestimmten Position im Array. Gleicher Brief
Ein Ausdruck des Zahlenaufrufs besteht aus einem Ausdruck, der ein Funktionsobjekt darstellt, und 0 mehr als 0 Parameterausdrücke. Die häufigste Methode, um einfache Ausdrücke in komplexe Ausdrücke zu kombinieren, sind Operatoren.
In diesem Kapitel (in diesem Artikel) werden alle JavaScript -Operatoren erläutert. Es erklärt auch Ausdrücke, an denen keine Operatoren beteiligt sind (z. B. Zugriff auf Array -Elemente und Funktionsaufrufe), und deren Syntax- und Programmierstil sind denen der C -Sprache sehr ähnlich.
1. Elementausdruck
Der einfachste Ausdruck ist "ursprünglicher Ausdruck", der kleinste Einheit eines Ausdrucks - sie enthalten keine anderen Ausdrücke. Die ursprünglichen Ausdrücke in JavaScript enthalten Konstanten oder direkte Mengen. Schlüsselwörter und Variablen.
Eine direkte Menge ist ein konstanter Wert, der direkt im Programm angezeigt wird. Sie sehen aus wie:
Die Codekopie lautet wie folgt:
1.23 // direkte Menge
"Hallo" // steh direkte Menge
/ muster/ // regelmäßiger Ausdruck direkte Menge
Einige reservierte Wörter in JavaScript bilden den ursprünglichen Ausdruck
Die Codekopie lautet wie folgt:
true // boolescher Wert: Richtig
Falsch // falsch
null // einen Wert zurückgeben: leer
Dies // gibt das "aktuelle" Objekt zurück
Durch das Erlernen von Kapitel 3 ist dies im Gegensatz zu anderen Schlüsselwörtern keine Konstante, und die Werte, die es in verschiedenen Teilen des Programms zurücksetzt, sind ebenfalls unterschiedlich. Dieses Schlüsselwort erscheint häufig in objektorientierter Programmierung. Dies gibt das Objekt der quadratischen Methode zurück.
Schließlich ist der dritte ursprüngliche Ausdruck eine Variable
Die Codekopie lautet wie folgt:
i // den Wert der Variablen i zurückgeben i
sum // den Summenwert zurückgeben
Undefiniert // ist im Gegensatz zu Null eine globale Variable, es ist kein Schlüsselwort
2. Initialisierungsausdrücke von Objekten und Arrays.
Objekt- und Array -Initialisierung ist tatsächlich neu erstellte Objekte und Arrays. Diese initialisierten Ausdrücke werden manchmal als "Objektdirektenmenge" und "Array -Direktmenge" bezeichnet. Im Gegensatz zu booleschen direkten Mengen sind sie jedoch keine ursprünglichen Ausdrücke, da die Mitglieder oder Elemente, die sie enthalten, unterexpressionen sind.
Die Syntax des Initialisierungsausdrucks eines Arrays ist sehr einfach. Beginnen wir unten
Der Initialisierungsausdruck eines Arrays besteht aus einem Paar quadratische Klammern und einer von Kommas getrennten Liste. Das Initialisierungsergebnis ist ein neu erstelltes Array. Elemente eines Arrays sind von Kommas getrennte Ausdrücke.
[] // ein leeres Array; [] Lassen Sie es leer, bedeutet, dass das Array keine Elemente hat
[1+2,3+4] // Array mit zwei Elementen, der erste ist 3, der zweite ist 7
Die Elementinitialisierungsexpression in einer Array -Initialisierungsexpression kann eine Array -Initialisierungsexpression sein. Das heißt, Ausdrücke können verschachtelt werden
Die Codekopie lautet wie folgt:
var mat = [[1,2,3], [4,5,6] [7,8,9]];
Elemente zwischen Listen im Array können weggelassen werden, und der Raum wird mit undefiniertem Platz gefüllt. Zum Beispiel:
Die Codekopie lautet wie folgt:
var a = [1 ,,,, 5]
Vier der Elemente sind undefiniert. Ein Komma bleibt am Ende der direkten Menge des Arrays, und ein neues Element mit einem undefinierten Wert wird nicht erstellt.
Objektinitialisierungsausdrücke sind den Array -Initialisierungsausdrücken sehr ähnlich, außer dass quadratische Klammern durch lockige Klammern ersetzt werden. Und jeder Wortausdruck enthält einen Attributnamen und einen Nicht-Colon als Präfix.
Die Codekopie lautet wie folgt:
var p = {x: 2.1, y: -3} // Ein Objekt mit zwei Attributmitgliedern
var q = {}; // leeres Objekt
qx = 2,1; Qy = -3; // Die Attributmitglieder von Q sind die gleichen wie die von p
Das Objekt kann beispielsweise auch direkt verschachtelt werden
Die Codekopie lautet wie folgt:
var anh = {links: {x: 2, y: 3},
Rechts: {x: 4, y: 5}}
Wenn JavaScript den Wert eines Objektinitialisierungsausdrucks berechnet, werden die Objektausdrücke jedes Mal berechnet und müssen keine konstanten Werte enthalten: Sie können jeder JavaScript -Ausdruck sein. In ähnlicher Weise kann der Name der Eigenschaft in der direkten Menge des Objekts eine Zeichenfolge anstelle einer Kennung sein. (Es ist sehr nützlich, wenn nur reservierte Wörter oder einige illegale Bezeichner als Attributnamen in dieser Zeile verwendet werden.)
Die Codekopie lautet wie folgt:
var Seite = 1;
var square = {"links": {x: px, y: py},
'rechts': {x: p.x+Seite, y: p.Y+Seite}}
In Kapitel 67 werden auch die Initialisierungsausdrücke von Objekten und Arrays erneut erörtert.
3. Funktionsausdrücke
Funktionsdefinitionsausdruck definiert eine JavaScript -Funktion. Der Wert des Ausdrucks ist diese neu definierte Funktion. In gewissem Sinne können Ausdrücke der Funktionsdefinition zu direkten Funktionen werden, und Funktionsausdrücke können als "direkte Funktionsmengen" bezeichnet werden, nachdem alle Objektinitialisierungsausdrücke auch als "direkte Objektmengen" bezeichnet werden. Ein typischer Ausdruck der Funktionsdefinition enthält die Schlüsselwortfunktion, gefolgt von einem Paar von Klammern, einer von Kommas getrennten Liste und der Liste 0 oder mehr Kennungen (Parameternamen). Folgen Sie dann dem in lockigen Klammern eingewickelten JavaScript -Code -Segment (Funktionskörper).
var square = function (x) {return x*x};
Funktionsdefinitionsausdrücke können auch den Namen der Funktion enthalten. Funktionen können auch durch Funktionsanweisungen und nicht durch Funktionsausdrücke definiert werden. Weitere Inhalte werden in Kapitel 8 beschrieben.
4. Attributzugriffsausdruck
Die Attributzugriffsausdruckoperation erhält den Wert eines Objekts oder eines Array -Elements. JavaScript definiert zwei Methoden für den Zugriff auf den Eigenschaft.
Die Codekopie lautet wie folgt:
Ausdruck . Eindrücker
Ausdruck [Ausdruck]
Der erste Weg besteht darin, einen Ausdruck zu schreiben, gefolgt von einer Periode und einer Kennung. Der Ausdruck gibt das Objekt an, und die Kennung gibt das zugegriffene Attribut Mingchuan an.
Kapitel 2 wird unter Verwendung von quadratischen Klammern geschrieben, was ein Ausdruck ist (diese Methode ist für Objekte und Arrays geeignet). Der zweite Ausdruck gibt die zugegriffene Mingchuan -Eigenschaft oder den Index an, das das zugegriffene Array -Element darstellt. Hier sind einige spezifische Beispiele
Die Codekopie lautet wie folgt:
OX // => 1x Attribut der Expression o
oyz // => 3 z -Ausdrucksattribut oy
o. ["x"] // => 1 Objekt o X -Attribut des X
A [1] // => 4 Element mit dem Ausdrucksindex A ist 1
A [2] ["1"] // => 6 Element mit Index 1 in Expression A [2]
a [0] .x // => 1: x -Ausdrucksattribut a [0]
Unabhängig von der Form der verwendeten Attributzugriffsausdrücke, die Ausdrücke vor "." und "[" werden immer zuerst bewertet. Wenn das Evaluierungsergebnis null oder undefiniert ist, wird der Ausdruck eine Typ -Fehlerausnahme ausgelöst, da keiner dieser Werte irgendwelche Attribute enthalten kann. Wenn das Betriebsergebnis kein Objekt oder ein Array ist, wandelt JavaScript es in ein Objekt um (Kapitel 3, Abschnitt 6).
Obwohl der Identifikator einfacher geschrieben ist, sollte angemerkt werden, dass diese Methode nur für den zugegriffenen Attributnamen gilt und ein rechtlicher Kennung ist. Und Sie müssen den Namen des zugegriffenen Attributs kennen. Wenn der Eigenschaftsname ein reserviertes Wort ist oder Räume und Zeichenzeichen enthält und eine Nummer (für ein Array) ist, müssen quadratische Klammern geschrieben werden. Wenn der Attributname ein Wert ist, der eher von einem Bediener als einem festen Wert abgeleitet wird, müssen quadratische Klammern geschrieben werden. (Kapitel 6, 2, 1 Bar)
5. Transportausdruck
Ein Aufrufexpression in JavaScript ist eine Syntaxdarstellung des Aufrufens (oder Ausführens) einer Funktion oder Methode. Es beginnt mit einem Funktionsausdruck, der sich auf die aufgerufene Funktion bezieht. Auf den Funktionsausdruck folgt ein Paar Klammern mit einer von Kommas getrennten Parameterliste. Es kann 0 Parameter oder mehrere Parameter geben.
f (0) // f ist ein Funktionsexpression: 0 ist ein Parameterausdruck.
Math.max (x, y, z) //math.max ist eine Funktion; x, y und z sind Parameter
a.sort () //a.sort () ist eine Funktion, die keine Parameter hat.
Wenn ein Ausdruck zur Bewertung erforderlich ist, berechnen Sie zunächst die Funktionsexpression und berechnen Sie dann den Parameterxpression, um einen Satz von Parameterwerten zu erhalten. Wenn der Wert des Funktionsausdrucks kein abrufbares Objekt ist, wird eine Typ -Fehlerausnahme ausgeworfen. Die Werte der Parameter werden dann den formalen Parametern zugeordnet, die beim Definieren der Funktion definiert sind. Führen Sie als nächstes den Funktionsorganisation aus. Wenn die Funktion die Rückgabeanweisung verwendet, um einen Rückgabewert anzugeben, ist dieser Rückgabewert der Wert des gesamten Aufrufausdrucks. Andernfalls ist der Wert des Anrufausdrucks undefiniert. Die Details des Funktionsaufrufs - einschließlich der Anzahl der formalen Parameterausdrücke und der Anzahl der tatsächlichen Parameter in der Funktionsdefinition - werden in Kapitel 8 ausführlich erläutert.
Jeder aufrufende Ausdruck enthält ein Paar Klammern und Ausdrücke vor den linken Klammern. Wenn dieser Ausdruck ein Ausdruck des Eigenschaftszugriffs ist, wird dieser Aufruf als "Methodeneinladung" bezeichnet. Bei der Ausführung eines Funktionskörpers in einem Methodenaufruf sind das Objekt und das Array, auf das als Attribute zugegriffen werden, der Zeiger davon in der Aufrufmethode. Diese Funktion ermöglicht es Funktionen (deren OO -Name "Methode" ist), ihr Hostobjekt (mehr zu Kapitel 9) aufzurufen.
6. Ausdruck von Objekterstellungen
Der Ausdruck des Objektkreises erstellt ein Objekt und ruft eine Funktion (Konstruktor) auf, um die Eigenschaften des Objekts zu initialisieren. Die Ausdrücke von Objekterstellungen sind der Funktionsaufrufe der Funktionsausdrücke sehr ähnlich, mit der Ausnahme, dass ein zusätzliches Schlüsselwort vor der Erstellung von Objekterstellungen vorhanden ist: Ausdrücke:
neues Objekt ()
neuer Punkt (2,3)
Wenn der Ausdruck der Objekterstellung keine Parameter an den Konstruktor übergeben werden muss, kann dieses Paar von Klammern weggelassen werden. Weitere Details des Konstruktors werden in Kapitel 9 erläutert
Neues Objekt
neuer Punkt
7. Überblick über die Operatoren
Operatoren in JavaScript werden verwendet, um Tabellenausdrücke, Vergleichsausdrücke, logische Ausdrücke, Zuordnungsausdrücke usw. zu berechnen.
Es ist zu beachten, dass die meisten Betreiber durch Interpunktionsmarken wie Delete und Instanz von dargestellt werden. Unabhängig davon, ob es sich um Keyword -Operatoren oder symbolische Operatoren handelt, sind die vertretenen Betreiber reguläre Operatoren, und ihre Syntax ist sehr präzise.
Die Priorität des Indexbetreibers ist sortiert und die Priorität des vorherigen Operators ist höher als die Priorität des nachfolgenden Operators. Die durch horizontalen Huafeng getrennten Betreiber haben unterschiedliche Prioritäten.
A repräsentiert die Bindung des Operators.
L von links nach rechts oder r (von rechts nach links)
Die Liste von Titel N enthält die Anzahl der Operanden.
Typ repräsentiert den Typ des erwarteten Operanden und den Ergebnistyp des Operators (nach dem Symbol "→")
| Betreiber | arbeiten | A | N | Typ |
| ++ | Vorne/nach dem Inkrement | R | 1 | lval → num |
| - | Vor und nachher reduzieren | R | 1 | lval → num |
| - - | Umgekehrt suchen | R | 1 | num → num |
| + | In Zahlen konvertieren | R | 1 | num → num |
| ~ | Stück für Stück umgekehrt | R | 1 | int → int |
| ! | Logisch nicht logisch | R | 1 | bool → bool |
| Löschen löschen | Attribute löschen | R | 1 | lval → bool |
| Typof | Betriebstyp erkennen | R | 1 | Any → str |
| Leere | Return undefined Value | R | 1 | Any → undef |
| *, /, % | Multiplizieren und teilen, um den Rest zu finden | L | 2 | num, num → num |
| +,- | Hinzufügen, subtrahieren | L | 2 | num, num → num |
| + | String -Verbindung | L | 2 | str, str → str → str |
| << | Linke Verschiebung | L | 2 | int, int → int |
| >> | Rechte Verschiebung | L | 2 | int, int → int |
| >>> | Unsigniertes Recht | L | 2 | int, int → int |
| <, <=,>,> = | Vergleichen Sie die Reihenfolge der Zahlen | L | 2 | num, num → bool |
| <, <=,>,> = | Vergleichen Sie die Bestellung in Buchstaben | L | 2 | str, str → bool |
| Instanz | Testobjektklasse | L | 2 | OBJ, Func → Bool |
| In | Testen Sie, ob das Attribut existiert | L | 2 | str, obj → bool |
| == | Gleiches Urteil | L | 2 | alle, alle → bool |
| ! = | Unzufriedenes Urteil | L | 2 | alle, alle → bool |
| === | Beurteilen Sie die Qualitäten | L | 2 | alle, alle → bool |
| ! == | Richter nicht konstant | L | 2 | alle, alle → bool |
| & | bitweise und | L | 2 | int, int → int |
| ^ | bitweise xor | L | 2 | int, int → int |
| | | bitweise oder | L | 2 | int, int → int |
| && | Logik und | L | 2 | alle, alle → Any |
| || | Logisch oder | L | 2 | alle, alle → Any |
| ?: | Bedingender Bediener | R | 3 | bool, alle, alle → Any |
| = | Variable Zuordnung oder Objektattributzuweisung | R | 2 | Lval, alle → Any |
*= /= %= += -= & = ^= | = << = >> = >>> = | Werte berechnen und zuweisen | R | 2 | Lval, alle → Any |
| Anwesend | Den ersten Operanden ignorieren, Gibt den zweiten Operanden zurück. | L | 2 | alle, alle → Any |
ich. Anzahl der Operanden
Die Betreiber können nach der Anzahl der Operanden klassifiziert werden.
Die meisten Operatoren in JavaScript sind binäre Operatoren, die zwei Ausdrücke zu einem etwas komplexeren Ausdruck kombinieren.
JavaScript unterstützt auch einige unäre Operatoren, die einen Ausdruck in einen anderen etwas komplexeren Ausdruck umwandeln. Der " -" Operator im Expression -x ist ein unärer Operator. Es soll einen negativen Wert für x finden.
JavaScript unterstützt einen ternären Operator: den bedingten Urteilsbetreiber "?:", Was drei Ausdrücke zu einem Ausdruck kombiniert
ii. Operandentyp und Ergebnistyp
Einige Operatoren können für jeden Datentyp verwendet werden, möchten jedoch weiterhin, dass sie Daten des angegebenen Typs betreiben.
III.LVALUE
Zuordnungsbetreiber und andere wenige Operatoren in der Tabelle erwarten, dass der Operand -Lval -Typ ein alter Begriff ist. Dies bedeutet, dass "Ausdrücke nur auf der linken Seite des Zuordnungsoperators erscheinen können". In JavaScript sind Variablen, Objekteigenschaften und Array -Elemente alle Lvalues. Die ECMAScript-Spezifikation ermöglicht es einer integrierten Reichweite, eine LVALUE zurückzugeben, aber definierte Funktionen können keine LVALUE zurückgeben.
IIII. Bedienerpriorität
In der obigen Tabelle werden die angezeigten Operatoren nach Priorität von hoch nach niedrig sortiert, wobei eine Reihe von Operatoren innerhalb jedes horizontalen Trennzeichens die gleiche Priorität hat. Die Priorität des Bedieners steuert die Reihenfolge, in der die Betreiber ausgeführt werden. Operatoren mit hoher (Tischplatte) werden immer höher ausgeführt als Operatoren mit niedriger Priorität (Ablauf der Tabelle).
Siehe den folgenden Ausdruck
w = x+y*z;
Der Multiplikationsoperator "*" hat eine höhere Priorität als die Zugabe "+", sodass zuerst eine Multiplikation ausgeführt wird. Dann hat der Zuweisungsoperator "=" die niedrigste Priorität. Daher wird die Zuordnungsoperation durchgeführt, nachdem der Ausdruck rechts das Ergebnis berechnet wird.
Die Priorität des Bedieners kann mit Gartenklammern geschrieben werden. Der obige Ausdruck kann so geschrieben werden.
w = (x + y) * z;
Es ist zu beachten, dass die Priorität von Ausdrucksformen des Eigentumszugriffs und des Aufrufens der Ausdrücke höher ist als die aller Betreiber in der Tabelle.
typeof my.function [x] (y)
Obwohl TypeOOF einer der operativen Prioritätsbetreiber ist, wird Typof auch nach zwei Eigenschaften zugänglich und Funktionsaufrufe ausgeführt.
Wenn Sie sich der Priorität des von Ihnen verwendeten Betreibers nicht sicher sind, besteht der einfachste Weg, Gartenklammern zu verwenden, um die Reihenfolge der Operationen zu erzwingen. Einige wichtige Regeln sollten auswendig gelernt werden: Die Multiplikation und die Teilung sind höher als Addition und Subtraktion, und die Priorität der Zuordnungsvorgänge ist sehr niedrig und werden normalerweise zuletzt ausgeführt.
iiiiiiii.operationalität
In diesem Abschnitt zeigt die Spalte A die Knoten des Operators. L bezieht sich auf die Kombination von links nach rechts, und R bezieht sich auf die Kombination von rechts nach links. Tuberkulose legt die Reihenfolge der Operationen in mehreren Operatorausdrücken mit gleicher Priorität fest.
Beispielsweise wird der Subtraktionsvorgang in einer Kombination von links nach rechts durchgeführt.
Die Codekopie lautet wie folgt:
w = x - y - z
Wie dieser Code:
Die Codekopie lautet wie folgt:
w = ((x - y) - z)
Umgekehrt der folgende Ausdruck:
Die Codekopie lautet wie folgt:
x = ~ -y;
w = x = y = z;
F = A? B: C? D: E? F: G;
Genau das gleiche wie dieser Code
Die Codekopie lautet wie folgt:
x = ~ (-y);
w = (x = (y = z));
Q = A? B: (C? D: (E? F: G))
Denn unary Operatoren, Zuweisungen und ternäre Bedingungsoperatoren haben eine Kombination von rechts nach links.
iiiiiiiiii.operation Order
Die Priorität und Bindung von Operatoren definieren ihre Operationsreihenfolge in der Zuordnungsgleichung, geben jedoch nicht die Reihenfolge der Operationen im Berechnungsprozess von Wortausdrücken an. JavaScript berechnet immer streng von links nach rechts ausdrücklich, zum Beispiel:
Im Ausdruck w = x+y*z wird zuerst der Ausdruck W berechnet, dann werden x, y und z berechnet und dann werden die Werte von y mit z multipliziert, wodurch der Wert von x hinzugefügt wird. Schließlich wird auf die Variable oder das Attribut, auf die der Ausdruck W genannt wird, genannt. Durch das Hinzufügen einer Kreisklammer zu einem Ausdruck wird die Beziehung zwischen Multiplikation, Addition und Zuordnungsoperationen verändert. Aber die Bestellung von links nach rechts ändert sich nicht.
8. Arithmetische Ausdrücke
Dieser Abschnitt deckt diese arithmetischen Berechnungsoperatoren sowie die arithmetischen Operationen an Operanden ab. Multiplikations-, Teilungs- und Subtraktionsbetreiber sind sehr einfach. Der Additionsbetrieb ist ein separater Abschnitt, da der Additionsbetreiber eine String -Verkettung bedienen kann und seine Typumwandlung etwas Besonderes ist.
Die grundlegenden arithmetischen Operatoren sind *, /, %, +, -. Zusätzlich zu +Addition sind andere Betreiber besonders einfach. Sie werden bei Bedarf nur in Zahlen umgewandelt, und dann können sie das Produkt, den Quotienten, das Rest (Modul) und den Unterschied finden. Alle diese Operationen, die nicht in Zahlen konvertiert werden können, werden in NAN -Werte umgewandelt. Wenn der Operand (oder das Konvertierungsergebnis) ein NAN -Wert ist, ist das arithmetische Betriebsergebnis auch NAN
Der Bediener "/" teilt den zweiten Operanden durch den ersten Operanden, wenn Sie Programmiersprachen verwendet haben, die Ganzzahl und Schwimmpunkt unterscheiden. Wenn Sie dann eine Ganzzahl durch eine Ganzzahl teilen, ist das gewünschte Ergebnis auch eine Ganzzahl. In JavaScript sind alle Zahlen schwimmende Punktzahlen, und das Ergebnis von Abteilungsoperationen ist auch Gleitkomma-Typen. Beispielsweise beträgt das Ergebnis von 5/2 2,5, nicht 2. Das Ergebnis der Operation mit dem Divisor 0 ist positiver Unendlichkeit oder negativer Unendlichkeit. Und das Ergebnis von 0/0 ist Nan. Alle diese Operationen melden keine Fehler.
Der Bediener "%" berechnet den Modul des ersten Operanden an den zweiten Operanden. Mit anderen Worten, der erste Operand wird durch den Rest des zweiten Operanden geteilt. Das Ergebnissymbol steht im Einklang mit dem (geteilten) Symbol der ersten Operation. Zum Beispiel beträgt das Ergebnis von 5%2 1 und -5%2 -1.
Die Operanden des Restbetreibers sind normalerweise Ganzzahlen, sind jedoch auch für Gleitkomma-Zahlen geeignet. 6,5%2,1 Ergebnis beträgt 0,2. (0.19999999999999999973)
ich. "+" Operator
Der Binärzusatzoperator "+" kann zwei Zahlen oder String -Verkettungsvorgänge hinzufügen:
Die Codekopie lautet wie folgt:
1+2 // => 3
"Hallo" + "" + "dort" // => "Hallo da"
"1"+"2" // => "12"
Wenn beide Operanden Zahlen oder Zeichenfolgen sind, sind die Berechnungsergebnisse offensichtlich. Für andere Fälle ist jedoch eine gewaltige Typumwandlung erforderlich. Und das Verhalten des Operators hängt vom Ergebnis der Umwandlung des Typs ab. Technisch gesehen lautet das Verhalten des Additionsbetreibers:
Wenn ein Operand ein Objekt ist, folgt das Objekt der Konvertierungsregel des Objekts zum ursprünglichen Wert zum ursprünglichen Klassenwert (siehe Kapitel 3, Abschnitt 8, 3). Das Datum führt die Konvertierung in der Objekt -ToString () -Methode durch, während andere Objekte die Konvertierung über die ValueOF () -Methode durchführen (falls die ValueOF () -Methode einen primitiven Wert zurückgibt). Da die meisten Objekte nicht über die verfügbare ValueOF () -Methode verfügen, verwenden sie die Methode toString (), um das Kriechen durchzuführen
Nachdem das Objekt zum ursprünglichen Wert konvertiert wurde, wird auch der andere Operand in eine Zeichenfolge konvertiert, wenn einer der Operationen eine Zeichenfolge ist. Dann machen Sie eine String -Verkettung.
Andernfalls werden beide Operanden in Zahlen (oder NAN) umgewandelt und dann hinzugefügt.
Hier sind einige Beispiele
Die Codekopie lautet wie folgt:
1 + 2 // => 3 Zugabe
"1" + "2" // => "12" String -Verbindung
"1" + 2 // => "12" werden in Saiten umgewandelt und verkettet
1 + {} // => "1 [Objektobjekt]": Das Objekt wird in eine Zeichenfolge konvertiert und dann wird die String -Verkettung durchgeführt.
true + true // => 2 boolescher Wert wird in eine Zahl konvertiert und hinzugefügt
2 + null // => 2 null konvertiert auf 0 und addieren
2 + undefined // => Nan undefinierte Konvertiten zur Addition zu NAN
Schließlich ist es wichtig zu beachten. Wenn der Pluszeichenbetrieb in Übereinstimmung mit Zeichenfolgen verwendet wird, sollte der Effekt der Zugabe auf die Reihenfolge der Operationen berücksichtigt werden. Das heißt, das Betriebsergebnis hängt beispielsweise von der Betriebsreihenfolge des Bedieners ab
Die Codekopie lautet wie folgt:
1 + 2 + "bmice" // => "3 Bmice"
1 + (2 + "BMICE") => "12BMICE"
ii. Unary Operator
Der UNERARY Operator wirkt in einem separaten Operanden. und einen neuen Wert generieren. In JavaScript haben Unary-Operatoren eine hohe Priorität und sind alle rechtskombiniert. Dieser Abschnitt beschreibt die unären Operatoren (+,-, ++ und-) und umwandeln bei Bedarf Vorgänge in Zahlen. Es sollte beachtet werden, dass + - ein unärer Operator ist und auch ein Binäroperator ist.
Ein-Yuaner-Addition+
Der Unarm Addition -Operator wandelt die Operandennummer in eine Nummer (oder NAN) um und gibt die konvertierte Nummer zurück. Wenn der Operand selbst eine Nummer ist, wird die Nummer direkt zurückgegeben.
One-Yuan-Subtraktion-
Wenn das Zeichen ein unärer Operator ist, wandelt es den Operanden nach Bedarf in eine Zahl um und ändert dann das Symbol des Betriebsergebnisses.
Inkrement ++
Inkrementieren Sie den Operator "++", um den Operanden zu erhöhen (+1), und der Operand ist ein LVALUE (Variable, Array -Element oder Objektattribut). Der Bediener wandelt Operanden in Zahlen um. Fügen Sie dann 1 zur Nummer hinzu und geben Sie den Wert nach dem Hinzufügen von 1 zur Variablen-, Array -Element- oder Objektattribut neu zu.
Increment ++ - Betrieb gibt den von seiner Position im Operanden abhängigen Wert zurück.
Wenn sich der Bediener vor der Operandennummer befindet, wird er als "Pre-Increment" -Operator bezeichnet, der den Operanden schrittweise berechnet und den berechneten Wert zurückgibt.
Wenn der Bediener nach dem Operand ist, wird er als "Post-Increment" -Preiber bezeichnet. Es führt inkrementelle Berechnungen im Operanden durch, gibt jedoch den nichtkrementierten Wert zurück, der für inkrementelle Berechnungen verwendet wird. wie
var i = 1, j = ++ i // Die Werte von i und j sind beide 2
var i = 1, j = i ++; // I ist 2, j ist 1
Es ist zu beachten, dass die Summe von ++ x = x+1 genau gleich ist. Der Operator "++" führt niemals String -Verkettungsvorgänge aus. Es wird immer den Operanden in eine Zahl umwandeln und ihn um 1 erhöhen. Wenn x die Zeichenfolge "1" ist, ist das Ergebnis von ++ x die Zahl 2 und x+1 die Zeichenfolge "11" ist die Zeichenfolge "11".
Die abnehmenden und inkrementierenden Operationen sind gleich, was Operanden in ein Array umwandelt und dann um 1 subtrahiert.
III. Bitbetreiber
Der Bitoperator kann bitgewiäre Operationen auf Bitärdaten ausführen, die durch Zahlen dargestellt werden. Obwohl es sich nicht um traditionelle reine mathematische Operationen handelt, werden sie hier auch als arithmetische Operatoren eingestuft, da sie auf Operationen numerischer Typen und Rückgabezahlen reagieren. Diese Operatoren sind in JavaScript nicht üblich. (Nicht hier beschrieben, bitte verwenden Sie Baidu für Details ~-~)
9. Relationale Ausdrücke
Dieser Abschnitt beschreibt die Beziehungsoperatoren von JavaScript. Relationale Operatoren werden verwendet, um die Beziehung zwischen zwei Werten (Gleichheit, weniger als oder "Attributen) zu testen und wahr und falsch zurückzugeben, je nachdem, ob die Beziehung besteht. Relationale Ausdrücke geben immer einen booleschen Wert zurück und verwenden normalerweise relationale Ausdrücke in wenn oder für Aussagen (Kapitel 5), um den Ausführungsprozess des Programms zu steuern.
In den nächsten Abschnitten wird über Gleichheit und ungleiche Operationen, Vergleichsbetreiber und die beiden anderen Beziehungsfiguren in JavaScript und Instanz sprechen
I Gleichheit und ungleiche Operatoren
Die Operatoren "==" und "===" werden verwendet, um zu vergleichen, ob zwei Werte gleich sind und die beiden Operatoren Operatoren jeder Art zulassen. Rückgabe true, wenn gleich, ansonsten false zurückgeben. "===" wird auch als strengen Gleichstellungsoperator (manchmal als Identitätsoperator bezeichnet) bezeichnet, mit dem festgestellt wird, ob zwei Operanden ausschließlich gleich sind. Der Operator "==" wird als Gleichstellungsoperator bezeichnet. Es wird verwendet, um festzustellen, ob zwei Operanden gleich sind. Die Gleichstellungsdefinition ist hier locker und ermöglicht die Typumwandlung.
JavaScript unterstützt die Operatoren "=", "==", "===", Sie sollten die Unterschiede zwischen (Zuordnung, Gleichheit, Identitäts-) Operatoren verstehen. Und seien Sie vorsichtig beim Programmieren. Um die Verwirrung zu verringern, sollte "=" "" "Get oder zugewiesen" genannt werden, "==" "sollte als" gleich "bezeichnet werden, und" === "sollte als" streng gleich "bezeichnet werden.
Die Regeln der "! =" Und "! ist ein boolescher Nicht-Operator. Wir nennen "! =", "! ==" ungleich und nicht streng gleich.
Der Vergleich von JavaScript -Objekten ist ein Vergleich der Referenzen, nicht ein Vergleich der Werte. Objekte und sich selbst sind gleich, aber sie sind nicht gleich Menschen und Objekten. Wenn zwei Objekte die gleiche Anzahl von Attributen, die gleichen Attributnamen und -werte haben, sind sie immer noch ungleich. Die Array -Elemente an der entsprechenden Position sind gleich und zwei Arrays sind ebenfalls ungleich.
Der strenge Gleichstellungsoperator "===" berechnet zuerst den Wert des Operanden und vergleichen Sie diese beiden Werte. Der Vergleichsprozess gibt keine Umwandlung.
Wenn die beiden Werttypen nicht gleich sein wollen, sind sie nicht gleich
Wenn beide Werte null oder undefiniert sind, sind sie nicht gleich
Wenn beide Werte boolean wahr oder falsch sind, sind sie gleich
Wenn einer der Werte Nan ist oder beide NAN sind, sind sie nicht gleich und Nan und andere Werte sind nicht gleich, einschließlich sich selbst.
Wenn zwei Werte Zahlen sind und gleich sind, sind sie gleich. Wenn ein Wert 0 ist und ein Wert -0 ist, sind sie auch gleich.
Wenn die beiden Werte Zeichenfolgen sind und die 16-stelligen Zahlen (siehe Kapitel 3, 2) in den entsprechenden Bits genau gleich sind, sind sie gleich. Wenn ihre Länge oder ihr Inhalt unterschiedlich sind, sind sie nicht gleich. Die beiden Zeichenfolgen haben möglicherweise genau die gleiche Funktion und die angezeigten Zeichen sind gleich, aber 16-Bit-Werte, die nicht codiert sind. JavaScript führt keine Standardkonvertierungen auf Unicode durch, sodass solche Zeichenfolgen im Vergleich zu den Operatoren "===" und "==" nicht gleich sind. String.LocalCompare () im dritten Teil bietet eine weitere Möglichkeit, Zeichenfolgen zu vergleichen.
Wenn zwei Referenzwerte auf dasselbe Objekt, Array oder Funktion deuten, sind sie gleich. Wenn sie auf verschiedene Objekte hinweisen, sind sie Ungleichheit, obwohl die beiden Objekte genau die gleichen Eigenschaften haben.
Der Gleichstellungsoperator "==" ähnelt dem Identitätsoperator, der Gleichstellungsoperator wird jedoch nicht strikt verglichen. Wenn die beiden Zahlen nicht vom gleichen Typ sind, versucht der Gleichstellungsoperator, eine Art Konvertierung durchzuführen, und vergleicht dann.
Wenn die beiden Operationen gleich sind, sind die Vergleichsregeln für die oben genannten Gleichstellungsoperatoren gleich. Wenn streng gleich, sind die Vergleichsergebnisse gleich. Wenn sie nicht streng gleich sind, sind die Vergleichsergebnisse nicht gleich.
Wenn die beiden Betriebstypen unterschiedlich sind, betrachtet der gleiche Operator sie auch gleich. Die Erkennung der Gleichheit folgt den folgenden Regeln und Typkonvertierungen:
Wenn ein Typ null ist und den anderen undefiniert sein, sind sie gleich
Wenn ein Wert eine Zahl ist und der andere eine Zeichenfolge ist, konvertieren Sie die Zeichenfolge zuerst in eine Zahl und verwenden Sie dann den konvertierten Wert für den Vergleich.
Wenn ein Wert wahr ist, wird er in 1 umgewandelt und dann verglichen. Wenn ein Wert falsch ist, wird er in 0 konvertiert und verglichen.
Wenn ein Wert ein Objekt ist und der andere eine Zahl oder eine Zeichenfolge ist, verwenden Sie die Konvertierungsregeln der Methode in Kapitel 3, Abschnitt 8, 3, um das Objekt in den ursprünglichen Wert umzuwandeln und dann zu vergleichen. Das Objekt wird über die Methode toString () in den ursprünglichen Wert konvertiert. Die integrierten Klassen im Kern der JavaScript-Sprache versuchen zunächst, ValueOF () zu verwenden und dann zu toString () zu verwenden. Zusätzlich zur Datumsklasse kann die Datumsklasse nur durch toString () konvertiert werden. Objekte, die sich nicht im Kern der JavaScript -Sprache befinden, werden durch in der Implementierung definierte Methoden in Originalwerte konvertiert.
Die Vergleiche zwischen anderen Typen sind nicht gleich
Hier ist ein kleines Beispiel für das gleiche Urteilsvermögen
"1" == True
Das Ergebnis dieses Ausdrucks ist wahr, was darauf hinweist, dass die Vergleichsergebnisse vollständig unterschiedlicher Werte Arten gleich sind. Der Boolesche Wert wird zuerst in die Zahl 1 konvertiert und dann wird der Vergleich durchgeführt. Als nächstes wird auch die Zeichenfolge "1" in die Zahl 1 konvertiert, da die Werte der beiden Zahlen gleich sind, sodass das Ergebnis wahr ist.
ii. Vergleichsbetreiber
Weniger als (<)
Wenn der erste Operand kleiner als der zweite Operand ist, ist das "<" -Operationsergebnis wahr, ansonsten ist es falsch
Weniger als oder gleich (<=)
Größer als (>)
Größer als oder gleich (> =)
.... (Keine detaillierte Einführung in die Bedeutung)
Die Operanden des Vergleichsbetreibers können von jeder Art sein. Es können jedoch nur Zahlen und Zeichenfolgen Vergleichsbetreiber durchführen, sodass die Operanden, die keine Zahlen und Zeichenfolgen sind, vom Typ Typ konvertiert werden. Die Typ -Conversion -Regeln sind wie folgt:
Wenn der Operand ein Objekt ist, wird er gemäß den in Abschnitt 3, Abschnitt 8, 3: Wenn valueOf () beschriebenen Konvertierungsregeln einen primitiven Wert zurückgibt, wird dieser ursprüngliche Wert direkt verwendet. Verwenden Sie ansonsten das Konvertierungsergebnis von toString () zum Vergleich.
Nach Konvertierung in den ursprünglichen Wert werden die beiden Zeichenfolgen in der Größenordnung des Alphabets verglichen. Die hier erwähnte "Alphabet-Reihenfolge" ist die Indexreihenfolge der 16-Bit-Unicode-Zeichen, die die beiden Saiten ausmachen.
Nachdem das Objekt in den ursprünglichen Wert konvertiert wurde, vergleichen beide Operanden, wenn mindestens ein Operand keine String ist, die Werte der Zahlen. 0 und -0 sind gleich. Jede andere Zahl in der unendlichen Wand ist groß (außer unendlich selbst), -inform ist kleiner als eine beliebige Zahl (außer sich selbst). Wenn ein Operand (oder konvertiert) NAN ist, gibt das Vergleichscharakter immer falsch zurück
Für numerische und String -Operatoren unterscheidet sich das Verhalten des Pluszeichenoperators vom Vergleichsbetreiber. Die ersteren bevorzugen Saiten und führen String -Verkettungsvorgänge aus, wenn einer seiner Operanden eine Zeichenfolge ist. Vergleichende Operatoren bevorzugen nur Zahlen, wenn beide Operanden Strings Strings sind. Nur dann wird der String -Vergleich durchgeführt.
Die Codekopie lautet wie folgt:
1 + 2 // => 3 Addition beträgt das Ergebnis 3
"1" + "2" // Verbindungszeichenfolge, das Ergebnis ist "12"
"1" + 2 // String verbinden, 2 wird in "2" konvertiert. Das Ergebnis ist "12".
11 <3 // Der Zahlenvergleich ist das Ergebnis wahr
"11" <"3" // Standvergleich, das Ergebnis ist wahr
"11" <3 // Vergleich der Zahlen, "11" wird in 11 umgewandelt, und das Ergebnis ist wahr
"Ein" <3 // Zahlenvergleich, "Eins" wird in Nan konvertiert, und das Ergebnis ist falsch
Schließlich sollte beachtet werden, dass bei der Beurteilung der Gleichstellung die Operatoren "<=" und "> =" nicht auf den Gleichstellungsoperator und die strikten Gleichstellungsvergleichsregeln beruhen. Im Gegenteil, der Betreiber Zhi, der weniger oder gleich ist, ist einfach "nicht größer als", während die Operation, die größer oder gleich ist, nur "nicht weniger als" ist. Mit nur einer Ausnahme, wenn der Operand (nach der Konvertierung) NAN ist, werden alle 4 Vergleichsbetreiber Fasle zurückgeben.
III.in Operator
Der In -Operator möchte, dass sein linker Operand eine Zeichenfolge ist oder in eine Zeichenfolge konvertiert werden kann, und hofft, dass es sich nach rechts um ein Objekt handelt. Wenn das Objekt rechts einen Attributnamen hat, der den linken Operandenwert bezeichnet wird, gibt der Ausdruck true zurück. Zum Beispiel
Die Codekopie lautet wie folgt:
var point = {
x: 1,
Y: 1
} // ein Objekt definieren
"x" in Punkt // => true Das Objekt hat eine Eigenschaft namens x
"Z" im Punkt // => Falsch Das Objekt hat keinen Namen Z -Attribut
"ToString" im Punkt // => True Object erbt die ToString -Methode
var data = [7, 8, 8]
"0" in Daten // => true das Array enthält 0
1 in Daten // => TRUE CONVERT -Nummer in die Zeichenfolge konvertieren
3 in Daten // => fase kein Element mit Index von 3
iiii.instance des Bedieners
Der Instanzoperator möchte, dass der linke Operator ein Objekt ist und der rechte Operand die Klasse des Objekts angibt. Wenn das Objekt links eine Instanz der Klasse rechts ist, gibt der Ausdruck wahr. Es ist verantwortlich für die Rückgabe falsch. Kapitel 9 wird darüber sprechen. Klassen von JavaScript -Objekten werden definiert, indem deren Konstruktoren initialisiert werden. Auf diese Weise sollte der richtige Operand von Instanz von einer Funktion sein. Zum Beispiel:
Die Codekopie lautet wie folgt:
var d = neues Datum (); // ein neues Objekt konstruieren
D Instanz des Datums; //The result of the calculation is true, d is created by Date()
d instanceof Object //计算结果为true ,所有的对象都是Object的实例
d instanceof Number //计算结果为false,d不是一个Number对象
var a = [1,2,3] //数组直接量创建数组
a instanceof Array //计算结果true a为数组
a instanceof Object //true 所有的数组都是对象
a instanceof RegExp //fasle 数组不是正则表达式
需要注意的是,所有对象都是Object的实例。当通过instanceof盘对一个对象是否为一个类的实例的时候,这个判断也叫“父类”(superclass)的检测,如果instanceof的左侧操作对象不是对象的话,instanceof返回false。如果右侧操作不是函数,则抛出类型错误的异常。
为了理解instanceof运算符是如何工作的,必须首先理解“原型类”(prototype chain),原型链作为javascript的继承机制,将在6章2节2小节详细描述。
为了计算表达式o instanceof f ,javascript笔仙首先计算f.prototyoe,然后在原型链中查询o,如果找到,那么o是f(或者f的父类)的一个实例,那么返回true。反之false
10.逻辑表达式
逻辑运算符"&&"、“||”、“!”是对操作进行布尔算术运算,经常和关系运算符一起配合使用,逻辑运算符将多个关系表达式组合起来组成一个更复杂的表达式。
ich. Logic and
"&&"运算符可以从三个不同的层次进行理解。最简单一层理解是,当操作数都是布尔值是,“&&”对两个布尔值执行布尔与(AND)操作,只有在第一个操作数和第二个操作数都是true的时候,它才返回true.如果其中有一个操作数为false.则它返回false.
"&&"长用来连接两个关系表达式
x == 0 && y == 0; //只有在x和y都是0时,才返回true
关系表达式总是返回true或false,因此当这样使用的时候,“&&”本身也返回true或false。关系运算符的优先级要比"&&"(和“||”)要高,因此类似这种表达式可以放心地书写,而不用补充园括号。
"&&"操作数并不一定是布尔值,回想一下,有些值是可以当做“真值”和“假值”的。(如3章3节,假值是:false null undefined 0 -0 NaN和"",所有和其它的值包括所有的对象都是真值)。对“&&”第二层理解是,“&&”是可以对真值和假值进行布尔与(AND)操作。如果两个操作数都是真值的,则那么返回一个真值;否则,至少一个操作数是假值的。javascript中在任何使用布尔值的地方的时候,表达式语句都会将其当做真值或假值来对待,因此实际上“&&”并不总是返回true和false.但也并无大碍。
需要注意的是,上文提到了运算符返回“真值”和“假值”,但并没说说明这个“真值”或者“假值”到底是什么值,为此我们深入讨论对“&&”第三层的理解。运算符首先计算左操作数的值,即首先计算“&&”左侧的表达式,如果计算结果是假值,那么整个表达式的结果一定是假值,因此“&&”这时简单的返回左操作的值,而并不会对右边的操作数进行计算。
Die Codekopie lautet wie folgt:
var o = {
x: 1
};
var p = null;
o && ox; //=>1 : 1:0是真值,因此返回值是ox
p && px //= null :p是假值,因此将其返回,而并不计算px
这对于理解“&&”可能不计算右操作数的情况至关重要,在上述代码中,变量P的值是null,而如果计算px的话则会抛出一个异常错误,因此,只有p为真值(不能是null或undefined)的情况下才计算px
"&&"的行为有时候被称为“短路”(short circuiting),我们经常能看到很多代码利用了这一也行来有条件的执行代码。例如下面的两条代码是等价的
Die Codekopie lautet wie folgt:
if (a == b) stop(); //只有a==b时才能调运stop()
(a == b) && stop(); //同上
一般来讲,当“&&”右侧的表达式具有副作用的时候(赋值,递增,递减和函数调用表达式)要格外小心。因为这些带有副作用的表达式的执行时候,依赖于左操作鼠的计算结果。
尽管“&&”可以按照第二层和第三层的理解进行一些复杂的表达式运算,但大多数的情况下,“&&”仅用来对真值和假值的做布尔计算。
ii. Logical or (||)
"||"运算符对两个操作数做布尔或(OR)运算。如果其中一个为真值,则返回真值,两个操作数都为假值,返回假值。
尽管“||”运算符大多情况下只是做简单的布尔或(OR)运算,和“&&”一样,也具备一些更复杂的行为,它首先计算第一个操作数的值,也就是说回首先计算左侧的表达式,如果计算结果为真,则返回真值,否则,再计算第二个值。
和“&&”一样,用于应该避免右操作数包含一些具有副作用的表达式,除非你目地明确在右侧使用带副作用的表达式,而有可能不会计算右侧的表达式。
这个运算符最常用的方式是用来从一组备选的表达中选取第一个真值的表达式。
Die Codekopie lautet wie folgt:
//如果max_width已经定义了,则直接使用它。赋值在preferences对象中查找max_width
//如果没有定义它,则使用一个写死的常量。
var max =max_width || preferences.max_windth || 500;
这种贯用法通常在函数体内,用来给参数提供默认值。
Die Codekopie lautet wie folgt:
//将o成功的属性复制到p中,并返回p
function copy(o, p) {
p = p || {}; //If no object is passed into the parameter p, a newly created object is used.
//函数体内的主逻辑
iii.逻辑非(!)
Der "!" operator is a unary operator that is placed before a separate operand. Its purpose is to invert the boolean value of the operand.
和"&&"、"||"运算符不同,“!”运算符首先将其操作数转换为布尔值(参考第三章的讲诉规则),然后再对布尔值求反。也就是"!"总是返回true和false。并且,可以通过使用两次逻辑非运算来得到一个值的布尔值:(!!x,参照第三章第八节第2小节)
“!”具有很高的优先级,并且和操作数紧密的绑在一起,如果希望对p && q,则需要园括号!(p && q)。如下代码:
Die Codekopie lautet wie folgt:
!(p && q) === !p || !Q
!(p || q) === !p && !q
对于p和q取任何值,这两个表达式永远成立。
11.赋值表达式
javascript使用"="运算符给变量或者属性来赋值,例如:
Die Codekopie lautet wie folgt:
i = 0 //将变量i设置为0
ox = 1 //将对象o的属性x 设置为1
“=”运算符希望它的左操作数为一个左值:一个变量或者对象属性(或数组元素),它的右操作鼠可以是任意的类型的任意值。赋值表达式的值就是右操作数的值。赋值表达式的副作用是,右操作数的值赋值给左侧的变量或对象属性。这样的话,后续对这个变量和对象的属性的引用都将得到这个值。
尽管赋值表达式的值非常简单,但有时候会看到一些复杂表达式包含赋值表达式的情况。例如:将赋值和检测操作放在一个表达式中:
Die Codekopie lautet wie folgt:
(a = b) == 0
如果这样的话,应该清楚地知道"="和"=="区别!,需要注意的是,“=”有非常低的优先级,通常在一个较长的表达式中用到一条赋值语句时,需要补充园括号以保障正确的运算顺序。
赋值操作符的结合性是从右至左,也就是说,一个表达式中出现了多个赋值运算符,运算顺序也从右至左,因此,可以通过以下方式对多个变量赋值。
Die Codekopie lautet wie folgt:
i=j=k=0; //把三个变量初始化为0
带操作的赋值运算:
除了常规的赋值运算外,javascript还支持需要其他的赋值运算符,这些运算符将赋值运算符合其他的运算符连接起来。提供一种更为快捷的运算方式。例如+=运算符执行的是加法运算符和赋值操作,下面的表达式:
total += salaes_tax;
和下面的表达式等价的
total = total + salaes_tax
运算符“+=”可以作用于数字或字符串,如果其操作是数字,它将执行加法运算和赋值操作;如果是字符串,他就执行字符串的连接和赋值操作。
此类型的运算符还包括,"-=","*=","&="等,如下表赋值运算符
运算符示例等价于
+=a+=ba=a+b
-=a-=ba=ab
*=a*=ba=a*b
/=a/=ba=a/b
%=a%=ba=a%b
<<=a<<=ba=a<<b
>>=a>>=ba=a>>b
>>>=a>>>=ba=a>>>b
&=a&=ba=a&b
|=a|=ba=a|b
^=a^=ba=a^b
大多数情况下,表达式为
a op =b
这里的op代表一个运算符,这个表达式等价于
a =a op b
在第一行中,表达式a计算了一次,在第二行中,表达式a计算了两次。
只有a包含具有副作用的表达式(比如函数调用和赋值操作)的时候,两者才不等价。如下两个表达式不等价
Die Codekopie lautet wie folgt:
data[i++] *= 2;
data[i++] = data[i++] * 2
12.表达式计算
和很多解释性语言一样,javascript同样可以解释运行由javascript源代码组成的字符串,并产生一个值。javascript通过全局函数eval()来完成这个工作。
eval("3+2") //=>5
动态判断源代码中的字符串是一种强大语言的特性,几乎没有必要在实际中应用。如果你使用了eval(),你应该仔细考虑真的需要它。
下面降价eval()基础用法,并介绍两种严格使用它的方法,从代码优化的角度来讲,这两种方法对原有的代码影响是最小的。
i.eval (eval()是一个函数,但由于它已经被当做运算符来对待了。)
eval()只有一个参数,如果传入的参数不是字符串,它直接返回这个参数。如果参数是字符串,它会把字符串当成javascript进行编译(parse),如果编译失败则抛出一个语法错误(SyntaxError)。如果编译成功,则开始执行这段代码,并返回字符串中最后一个表达式或语句的值,如果最后一个表达式没有语句或者值,则最终返回undefined。如果字符串抛出一个异常,这个异常把该调用的传给eval()
关于eveal()最重要的是,它使用了调用它的变量作用域环境,也就是说,它查找变量的值和定义新变量和函数的操作和局部的代码作用域中的代码一样。如果一个函数定义了一个局部变量x,然后调用了eval("x"),它会返回局部变量的值。如果它调用eval("x=1"),它会改变局部变量的值。如果函数调用了eval("var y=3;")它声明一个新的局部变量y。同样的,一个函数可以通过如下代码声明一个局部函数:
eval("function f(){return x+1;}");
如果最顶层的代码中调用了eval()。当然它会作用于全局变量和全局函数。
ii. Global eval()
eval()具有改变局部变量的能力,这对javascript优化器来说,是一个很大的问题,然而作为一种权宜之计,javascript征对那行调用了eval()函数所做的优化并不多。但当脚本定义了一个别名,并且用令一个名称来调用它,javascript解释器又如何工作呢,为了javascript解释器更加简化。ECMAScipt3标准规定了任何解释器都不允许对eval()赋予别名。如果eval()使用别的别名来调用的话,则会抛出EvalError异常。
实际上,大多数的实现并不是这样做的。当通过别名调用时,eval()会将其字符串当成顶层的全局代码来执行。执行代码可能会定义新的全局变量和全局函数。执行的代码可能会定义新的全局变量和全局函数,或者给全局变量赋值。但却不能修改或修改主调函数中的局部变量,因此这不会影响到函数内的代码优化。
ECMAScript5是反对使用EvalError的,并且规范了eval()的行为。“直接的eval”,当直接使用非限定的“eval”名称,来调用eval()函数时,它总共是在它的上下文作用域内支线。其它间接调用则使用全局函数为其上下文作用域。并且无法读、写、定义局部变量和函数。下面有一段代码实例:
Die Codekopie lautet wie folgt:
var geval = eval; //使用别名调用eval将是全局eval
var x = "global",
y = "global"; //两个全局变量
function f() { //函数内执行的局部eval
var x = "local" //定于局部变量
eval("x += 'changed';"); //直接eval更改了局部变量的
Rückkehr x; //Return the changed local variable
}
function g() { //这个函数执行了全局eval
var y = "local" //定义了局部变量
geval("y += 'changed';"); //间接改变了局部变量的值
return y; //返回未更改的局部变量
}
console.log(f(), x); //更改了局部变量,输出local changed global
console.log(g(), y); //更改了全局变量,输出local globalchanged
13.其它运算符。
javascript支持很多其它各种各样的运算符。
ich. Conditional operator (?:)
The conditional operator is the only ternary operator in javascript. Usually this operator is written as "?:". This operator has the third operand, the first operand is before "?", and the second operand is between "?" Und ":". The third operand is long after ":", e.g.
x > 0 ? x : -x; //求x的绝对值
条件运算符的操作数可以是任意类型。第一个操作数当成布尔值,如果它是真值,那么将计算第二个操作数,并返回计算结果。赋值如果第一个值操作数是假值,那么将计算第三个操作数。并返回计算结果。第二个和第三个操作数总会计算其中之一。不可能两者同时进行。其实使用if语句也达到同样的效果(5.4.1),“?:”运算符只是提供了一种简写形式。这里是一个"?:"的典型使用场景,判断一个变量是否有定义,如果有定义则使用它,如果无定义,则使用一个默认值。
Die Codekopie lautet wie folgt:
grett = "hello" + (username ? username : "three");
和以下的代码是等价的,但上面的更加简洁
Die Codekopie lautet wie folgt:
grett = "hello";
if (username)
grett += username;
anders
grett + "three"
ii.typeof()运算符
typeof是一元运算符,放在单个操作数前面,操作数可以是任何类型,返回值表示操作类型的一个字符串。
Die Codekopie lautet wie folgt:
x __ typeof x
undefined __ "undefined"
null __ "object"
ture或false __"boolean"
任意数字或NaN __ "Number"
任意字符串__ "String"
任意函数__ "function"
任意内容对象(非函数)__ "object"
任意宿主对象__ 由编译器各自实现的字符串,但不是"undefined" "boolean" "number" "string"
typeof最常用的用法写在表达式中们就像这样
(typeof value == "string") ? "" + value + "":value;
typeof运算符同样在swith语句中(5.4.3)非常有用,需要注意的是,typeof运算可以带上园括号。这样让typeof看起来像一个函数名,而非关键字
typeof(i)
iii.delete运算符
delete是一元操作符,它用来删除对象的属性或者数组的元素。就像赋值、递增、递减运算符一样。delete也是具有副作用的。它是用来做删除操作的。不是用来返回一个值的。
Die Codekopie lautet wie folgt:
var o = {
x: 1,
y: 2
}
delete ox;
"x" in o; //=>false
var a = [1, 2, 3];
delete a[2]; // 删除数组中最后一个元素
2 in a; //=> false 元素2已经在数组中不存在了
a.length; //=>3,注意,数组长度并没有改变,尽管上一行删除了这个元素,但删除操作留下了一个洞。实际上并没有修改数组的长度,因此a的长度仍然为3
需要注意的是,删除属性或删除数组元素不仅仅设置了一个undefined值,当删除一个属性时,这个属性不复存在。读取一个不存在的值将会返回undefined.关于delete删除还有严格模式下的一些情况,需要学习的人自己试验,这里给一些例子。
Die Codekopie lautet wie folgt:
var o = {x: 1,y: 2};
delete ox; //删除一个对象属性,返回true
typeof ox; //属性不存在,返回"undefined"
delete ox; //删除不存在的属性,返回true;
delete o; //不能删除通过var关键字声明的变量,返回false
delete 1; //参数不是一个左值。
this.x = 1;// 给全局定义一个属性,这里没有使用var
delete x ; //试图删除它,在非严格模式下返回true
//在严格模式下回抛出异常,这时使用"delete this.x"来代替
X; // An error occurred during runtime, no x is defined
6章第三节还有关于delete的讨论。
iii.void运算符。
void是一元运算符,在出现操作数之前,操作数可以是任何类型。这个运算符并不是经常使用:操作数会照常计算,但会忽略计算结果并返回undefined。由于void会忽略操作数的值,因此在操作数具有副作用时使用void来程序更有意义。
这个最常用的带客户端url.在url写带有副作用的表达式,而void则让浏览器不显示在这个表达式的运算结果。
Die Codekopie lautet wie folgt:
<a href="javascript:void window.open();">new</a>
iiii.逗号运算符。(,)
逗号运算符是二元运算符,它的操作数可以是任意类型。它首先计算左操作数,然后计算右操作数。
Die Codekopie lautet wie folgt:
i = 0, j = 1, k = 2;
它和下面的代码基本上等价的
i = 0; j = 1; k = 2;
总是会计算左侧的表达式,但计算结果忽略掉,也就是说,只有左侧表达式具有副作用,才会使用逗号运算让代码变得更通畅。逗号运算符最常用的场景是for循环中,这个for循环通常有多个循环变量。
Die Codekopie lautet wie folgt:
//for循环中的第一个逗号是var语句的一部分
//第二个逗号是逗号运算符
//它将两个表达式(i++和j++)放在一条(for循环中)语句中
for (var i = 0, j = 10; i < j; i++, j--);
console.log(i + j);