Suche…
Bemerkungen
Bei der Verwendung von booleschem Zwang gelten die folgenden Werte als "Fälschung" :
-
false
-
0
-
""
(leere Zeichenfolge) -
null
-
undefined
-
NaN
(keine Zahl, zB0/0
) -
document.all
¹ (Browserkontext)
Alles andere gilt als "wahr" .
Logikoperatoren mit Booleans
var x = true,
y = false;
UND
Dieser Operator gibt true zurück, wenn beide Ausdrücke als true ausgewertet werden. Dieser boolesche Operator verwendet einen Kurzschluss und wertet y
nicht aus, wenn x
false
.
x && y;
Dies gibt false zurück, da y
falsch ist.
ODER
Dieser Operator gibt true zurück, wenn einer der beiden Ausdrücke als true ausgewertet wird. Dieser boolesche Operator verwendet einen Kurzschluss und y
wird nicht ausgewertet, wenn x
als true
bewertet wird.
x || y;
Dies wird wahr zurückgeben, da x
wahr ist.
NICHT
Dieser Operator gibt "false" zurück, wenn der Ausdruck auf der rechten Seite als "true" ausgewertet wird.
!x;
Dies gibt false zurück, da x
wahr ist.
Abstrakte Gleichheit (==)
Operanden des abstrakten Gleichheitsoperators werden verglichen, nachdem sie in einen allgemeinen Typ konvertiert wurden. Wie diese Konvertierung abläuft, basiert auf den Angaben des Operators:
Spezifikation für den Operator ==
:
7.2.13 Vergleich der abstrakten Gleichheit
Der Vergleichx == y
, wobeix
undy
Werte sind, erzeugttrue
oderfalse
. Ein solcher Vergleich wird wie folgt durchgeführt:
- Wenn
Type(x)
mitType(y)
identisch ist, gilt Folgendes:
- ein.
x === y
das Ergebnis des strengen Gleichheitsvergleichsx === y
.
- Wenn
x
null
undy
undefined
, geben Sietrue
.- Wenn
x
undefined
undy
null
, geben Sietrue
.- Wenn
Type(x)
Number
undType(y)
String
, geben Sie das Ergebnis des Vergleichs zurück.x == ToNumber(y)
.- Wenn
Type(x)
String
undType(y)
Number
, geben Sie das Ergebnis des VergleichsToNumber(x) == y
.- Wenn
Type(x)
Boolean
, geben Sie das Ergebnis des VergleichsToNumber(x) == y
.- Wenn
Type(y)
Boolean
, geben Sie das Ergebnis descomparison x == ToNumber(y)
.- Wenn
Type(x)
entwederString
,Number
oderSymbol
undType(y)
Object
, geben Sie das Ergebnis des Vergleichs zurück.x == ToPrimitive(y)
.- Wenn
Type(x)
Objekt undType(y)
entwederString
,Number
oderSymbol
, geben Sie das Ergebnis des Vergleichs anToPrimitive(x) == y
.false
Beispiele:
1 == 1; // true
1 == true; // true (operand converted to number: true => 1)
1 == '1'; // true (operand converted to number: '1' => 1 )
1 == '1.00'; // true
1 == '1.00000000001'; // false
1 == '1.00000000000000001'; // true (true due to precision loss)
null == undefined; // true (spec #2)
1 == 2; // false
0 == false; // true
0 == undefined; // false
0 == ""; // true
Vergleichsoperatoren (<, <=,>,> =)
Wenn beide Operanden numerisch sind, werden sie normalerweise verglichen:
1 < 2 // true
2 <= 2 // true
3 >= 5 // false
true < false // false (implicitly converted to numbers, 1 > 0)
Wenn beide Operanden Zeichenfolgen sind, werden sie lexikographisch (in alphabetischer Reihenfolge) verglichen:
'a' < 'b' // true
'1' < '2' // true
'100' > '12' // false ('100' is less than '12' lexicographically!)
Wenn ein Operand eine Zeichenfolge und der andere eine Zahl ist, wird die Zeichenfolge vor dem Vergleich in eine Zahl umgewandelt:
'1' < 2 // true
'3' > 2 // true
true > '2' // false (true implicitly converted to number, 1 < 2)
Wenn die Zeichenfolge nicht numerisch ist, gibt die numerische Konvertierung NaN
(keine Zahl) zurück. Beim Vergleich mit NaN
immer false
:
1 < 'abc' // false
1 > 'abc' // false
Seien Sie jedoch vorsichtig, wenn Sie einen numerischen Wert mit null
, undefined
oder leeren Zeichenfolgen vergleichen:
1 > '' // true
1 < '' // false
1 > null // true
1 < null // false
1 > undefined // false
1 < undefined // false
Wenn ein Operand ein Objekt ist , und der andere ist eine Zahl, das Objekt in eine Zahl umgewandelt wird , bevor comparison.So null
ist , weil Fall Number(null);//0
new Date(2015)< 1479480185280 // true
null > -1 //true
({toString:function(){return 123}}) > 122 //true
Ungleichheit
Operator !=
==
die Umkehrung des Operators ==
.
Gibt true
wenn die Operanden nicht gleich sind.
Die Javascript-Engine versucht, beide Operanden in übereinstimmende Typen zu konvertieren, wenn sie nicht vom selben Typ sind. Hinweis: Wenn die beiden Operanden unterschiedliche interne Referenzen im Speicher haben, wird false
zurückgegeben.
Probe:
1 != '1' // false
1 != 2 // true
Im obigen Beispiel ist 1 != '1'
false
da ein primitiver Zahlentyp mit einem char
Wert verglichen wird. Daher kümmert sich die Javascript-Engine nicht um den Datentyp des RHS-Werts.
Operator ===
!==
ist die Umkehrung des Operators ===
. Gibt true zurück, wenn die Operanden nicht gleich sind oder wenn ihre Typen nicht übereinstimmen.
Beispiel:
1 !== '1' // true
1 !== 2 // true
1 !== 1 // false
Logikoperatoren mit nicht-booleschen Werten (boolescher Zwang)
Das logische ODER ( ||
), das von links nach rechts liest, ergibt den ersten Wahrheitswert . Wenn kein wahrer Wert gefunden wird, wird der letzte Wert zurückgegeben.
var a = 'hello' || ''; // a = 'hello'
var b = '' || []; // b = []
var c = '' || undefined; // c = undefined
var d = 1 || 5; // d = 1
var e = 0 || {}; // e = {}
var f = 0 || '' || 5; // f = 5
var g = '' || 'yay' || 'boo'; // g = 'yay'
Das logische UND ( &&
), das von links nach rechts liest, wird auf den ersten falschen Wert ausgewertet. Wenn kein falsey- Wert gefunden wird, wird der letzte Wert zurückgegeben.
var a = 'hello' && ''; // a = ''
var b = '' && []; // b = ''
var c = undefined && 0; // c = undefined
var d = 1 && 5; // d = 5
var e = 0 && {}; // e = 0
var f = 'hi' && [] && 'done'; // f = 'done'
var g = 'bye' && undefined && 'adios'; // g = undefined
Dieser Trick kann beispielsweise verwendet werden, um einen Standardwert für ein Funktionsargument (vor ES6) festzulegen.
var foo = function(val) {
// if val evaluates to falsey, 'default' will be returned instead.
return val || 'default';
}
console.log( foo('burger') ); // burger
console.log( foo(100) ); // 100
console.log( foo([]) ); // []
console.log( foo(0) ); // default
console.log( foo(undefined) ); // default
Denken Sie jedoch daran, dass für Argumente 0
und (in einem geringeren Ausmaß) die leere Zeichenfolge auch gültige Werte sind, die explizit übergeben werden können und einen Standardwert überschreiben, den sie bei diesem Muster nicht (weil sie) verwenden sind falsch ).
Null und Undefiniert
Die Unterschiede zwischen null
und undefined
null
und undefined
teilen die abstrakte Gleichheit ==
aber keine strikte Gleichheit ===
,
null == undefined // true
null === undefined // false
Sie stellen etwas unterschiedliche Dinge dar:
-
undefined
für das Fehlen eines Werts , z. B. bevor ein Bezeichner / eine Objekteigenschaft erstellt wurde, oder in der Zeit zwischen der Erstellung des Bezeichners / Funktionsparameters und seiner ersten Gruppe (falls vorhanden). -
null
für das absichtliche Fehlen eines Werts für einen Bezeichner oder eine Eigenschaft, die bereits erstellt wurde.
Es gibt verschiedene Arten von Syntax:
-
undefined
ist eine Eigenschaft des globalen Objekts , die normalerweise im globalen Bereich unveränderlich ist. Dies bedeutet, dass Sie überall dort, wo Sie einen anderen Bezeichner als im globalen Namespace definieren können,undefined
aus diesem Bereich ausblenden können (obwohl Dinge immer nochundefined
). -
null
ist ein Wortliteral , daher kann seine Bedeutung niemals geändert werden. Wenn Sie dies versuchen, wird ein Fehler ausgegeben .
Die Ähnlichkeiten zwischen null
und undefined
null
und undefined
sind beide falsch.
if (null) console.log("won't be logged");
if (undefined) console.log("won't be logged");
Weder null
noch undefined
gleich false
(siehe diese Frage ).
false == undefined // false
false == null // false
false === undefined // false
false === null // false
undefined
- Wenn der aktuelle Bereich nicht vertraut werden kann, verwenden Sie etwas , was zu undefinierten auswertet, zum Beispiel
void 0;
. - Wenn
undefined
von einem anderen Wert gespiegelt wird, ist dies genauso schlecht wie das Spiegeln vonArray
oderNumber
. - Vermeiden Sie , etwas als
undefined
. Wenn Sie eine Immobilie bar aus einem Objekt entfernen möchtenfoo
,delete foo.bar;
stattdessen. - Der Bestätigungs-Identifier
foo
gegenundefined
könnte einen Referenzfehler auslösen , stattdessentypeof foo
gegen"undefined"
.
NaN-Eigenschaft des globalen Objekts
NaN
(" N a a N Umber") ist ein spezieller Wert, der durch den IEEE-Standard für Fließkomma-Arithmetik definiert wird. Dieser Wert wird verwendet, wenn ein nicht numerischer Wert angegeben wird, aber eine Zahl erwartet wird ( 1 * "two"
) oder wenn eine Berechnung haben keine gültige number
Ergebnis ( Math.sqrt(-1)
).
Gleichheits- oder relationale Vergleiche mit NaN
Wert false
, selbst wenn sie mit sich selbst verglichen werden. NaN
soll das Ergebnis einer unsinnigen Berechnung bezeichnen und ist daher nicht gleich dem Ergebnis anderer unsinniger Berechnungen.
(1 * "two") === NaN //false
NaN === 0; // false
NaN === NaN; // false
Number.NaN === NaN; // false
NaN < 0; // false
NaN > 0; // false
NaN > 0; // false
NaN >= NaN; // false
NaN >= 'two'; // false
Nichtgleiche Vergleiche geben immer " true
:
NaN !== 0; // true
NaN !== NaN; // true
Überprüfen, ob ein Wert NaN ist
Sie können einen Wert oder Ausdruck für NaN
mithilfe der Funktion Number.isNaN () testen :
Number.isNaN(NaN); // true
Number.isNaN(0 / 0); // true
Number.isNaN('str' - 12); // true
Number.isNaN(24); // false
Number.isNaN('24'); // false
Number.isNaN(1 / 0); // false
Number.isNaN(Infinity); // false
Number.isNaN('str'); // false
Number.isNaN(undefined); // false
Number.isNaN({}); // false
Sie können prüfen, ob ein Wert NaN
indem Sie ihn mit sich selbst vergleichen:
value !== value; // true for NaN, false for any other value
Sie können den folgenden Polyfill für Number.isNaN()
:
Number.isNaN = Number.isNaN || function(value) {
return value !== value;
}
Im Gegensatz dazu gibt die globale Funktion isNaN()
true
nicht nur für NaN
, sondern auch für jeden Wert oder Ausdruck, der nicht in eine Zahl umgewandelt werden kann:
isNaN(NaN); // true
isNaN(0 / 0); // true
isNaN('str' - 12); // true
isNaN(24); // false
isNaN('24'); // false
isNaN(Infinity); // false
isNaN('str'); // true
isNaN(undefined); // true
isNaN({}); // true
ECMAScript definiert einen "Gleichheits" -Algorithmus namens SameValue
, der seit ECMAScript 6 mit Object.is
aufgerufen werden Object.is
. Im Gegensatz zum Vergleich von ==
und ===
wird die Verwendung von Object.is()
NaN
als identisch mit sich selbst (und -0
als nicht identisch mit +0
) behandeln:
Object.is(NaN, NaN) // true
Object.is(+0, 0) // false
NaN === NaN // false
+0 === 0 // true
Sie können den folgenden Polyfill für Object.is()
(von MDN ) verwenden:
if (!Object.is) {
Object.is = function(x, y) {
// SameValue algorithm
if (x === y) { // Steps 1-5, 7-10
// Steps 6.b-6.e: +0 != -0
return x !== 0 || 1 / x === 1 / y;
} else {
// Step 6.a: NaN == NaN
return x !== x && y !== y;
}
};
}
Punkte zu beachten
NaN selbst ist eine Zahl, was bedeutet, dass sie nicht mit der Zeichenfolge "NaN" übereinstimmt, und vor allem (wenn auch vielleicht ungewollt):
typeof(NaN) === "number"; //true
Kurzschluss bei booleschen Operatoren
Der and-Operator ( &&
) und der or-Operator ( ||
) verwenden Kurzschlüsse, um unnötige Arbeit zu vermeiden, wenn sich das Ergebnis der Operation nicht mit der zusätzlichen Arbeit ändert.
In x && y
wird y
nicht ausgewertet, wenn x
false
ergibt, da der gesamte Ausdruck garantiert false
.
In x || y
, y
wird nicht ausgewertet, wenn x
als true
ausgewertet wird, da der gesamte Ausdruck garantiert true
.
Beispiel mit Funktionen
Übernehmen Sie die folgenden zwei Funktionen:
function T() { // True
console.log("T");
return true;
}
function F() { // False
console.log("F");
return false;
}
Beispiel 1
T() && F(); // false
Ausgabe:
'T'
'F'
Beispiel 2
F() && T(); // false
Ausgabe:
'F'
Beispiel 3
T() || F(); // true
Ausgabe:
'T'
Beispiel 4
F() || T(); // true
Ausgabe:
'F'
'T'
Kurzschluss, um Fehler zu vermeiden
var obj; // object has value of undefined
if(obj.property){ }// TypeError: Cannot read property 'property' of undefined
if(obj.property && obj !== undefined){}// Line A TypeError: Cannot read property 'property' of undefined
Zeile A: Wenn Sie die Reihenfolge umkehren, verhindert die erste Bedingungsanweisung den Fehler auf der zweiten, indem Sie ihn nicht ausführen, wenn er den Fehler auslösen würde
if(obj !== undefined && obj.property){}; // no error thrown
Sollte aber nur verwendet werden, wenn Sie undefined
erwarten
if(typeof obj === "object" && obj.property){}; // safe option but slower
Kurzschluss, um einen Standardwert bereitzustellen
Die ||
Der Operator kann verwendet werden, um entweder einen "Wahrheitswert" oder den Standardwert auszuwählen.
Dies kann beispielsweise verwendet werden, um sicherzustellen, dass ein nullwertfähiger Wert in einen nicht nullwertfähigen Wert konvertiert wird:
var nullableObj = null;
var obj = nullableObj || {}; // this selects {}
var nullableObj2 = {x: 5};
var obj2 = nullableObj2 || {} // this selects {x: 5}
Oder um den ersten Wahrheitswert zurückzugeben
var truthyValue = {x: 10};
return truthyValue || {}; // will return {x: 10}
Dasselbe kann verwendet werden, um mehrmals zurückzugreifen:
envVariable || configValue || defaultConstValue // select the first "truthy" of these
Kurzschließen, um eine optionale Funktion aufzurufen
Mit dem Operator &&
kann ein Callback nur ausgewertet werden, wenn er übergeben wird:
function myMethod(cb) {
// This can be simplified
if (cb) {
cb();
}
// To this
cb && cb();
}
Der obige Test bestätigt natürlich nicht, dass es sich bei cb
tatsächlich um eine function
und nicht nur um eine Object
/ Array
/ String
/ Number
.
Abstrakte Gleichheit / Ungleichheit und Typumwandlung
Das Problem
Die abstrakten Gleichheitsoperatoren ( ==
und !=
) Konvertieren ihre Operanden, wenn die Operandentypen nicht übereinstimmen. Diese Art von Zwang ist eine häufige Verwirrung über die Ergebnisse dieser Operatoren, insbesondere sind diese Operatoren nicht immer wie von mir erwartet unempfindlich.
"" == 0; // true A
0 == "0"; // true A
"" == "0"; // false B
false == 0; // true
false == "0"; // true
"" != 0; // false A
0 != "0"; // false A
"" != "0"; // true B
false != 0; // false
false != "0"; // false
Die Ergebnisse werden sinnvoll, wenn Sie bedenken, wie JavaScript leere Zeichenfolgen in Zahlen konvertiert.
Number(""); // 0
Number("0"); // 0
Number(false); // 0
Die Lösung
In der Anweisung false B
sind beide Operanden Strings ( ""
und "0"
), daher gibt es keine Typumwandlung. Da ""
und "0"
nicht den gleichen Wert haben, ist "" == "0"
false
wie erwartet.
Eine Möglichkeit, unerwartetes Verhalten zu vermeiden, besteht darin, sicherzustellen, dass Sie immer Operanden desselben Typs vergleichen. Wenn Sie beispielsweise die Ergebnisse des numerischen Vergleichs verwenden möchten, verwenden Sie die explizite Konvertierung:
var test = (a,b) => Number(a) == Number(b);
test("", 0); // true;
test("0", 0); // true
test("", "0"); // true;
test("abc", "abc"); // false as operands are not numbers
Oder, wenn Sie einen Stringvergleich wünschen:
var test = (a,b) => String(a) == String(b);
test("", 0); // false;
test("0", 0); // true
test("", "0"); // false;
Randnotiz : Number("0")
und new Number("0")
ist nicht dasselbe! Während Ersteres eine Typkonvertierung durchführt, erstellt Letzteres ein neues Objekt. Objekte werden anhand von Verweisen verglichen und nicht anhand von Werten, wodurch die Ergebnisse unten erläutert werden.
Number("0") == Number("0"); // true;
new Number("0") == new Number("0"); // false
Schließlich haben Sie die Möglichkeit, strikte Gleichheits- und Ungleichheitsoperatoren zu verwenden, die keine impliziten Typkonvertierungen durchführen.
"" === 0; // false
0 === "0"; // false
"" === "0"; // false
Weiterführende Hinweise zu diesem Thema finden Sie hier:
Welcher Operator equals (== vs ===) sollte in JavaScript-Vergleichen verwendet werden? .
Leeres Array
/* ToNumber(ToPrimitive([])) == ToNumber(false) */
[] == false; // true
Wenn [].toString()
ausgeführt wird, ruft es [].join()
falls vorhanden, oder Object.prototype.toString()
ansonsten. Dieser Vergleich gibt " true
da [].join()
''
zurückgibt ''
das in 0
wurde und "false ToNumber" entspricht .
Beachten Sie jedoch, dass alle Objekte wahr sind und Array
eine Instanz von Object
:
// Internally this is evaluated as ToBoolean([]) === true ? 'truthy' : 'falsy'
[] ? 'truthy' : 'falsy'; // 'truthy'
Gleichheitsvergleichsoperationen
JavaScript bietet vier verschiedene Gleichheitsvergleichsoperationen.
SameValue
Sie gibt true
zurück true
wenn beide Operanden zu demselben Type gehören und denselben Wert haben.
Hinweis: Der Wert eines Objekts ist eine Referenz.
Sie können diesen Vergleichsalgorithmus über Object.is
(ECMAScript 6) verwenden.
Beispiele:
Object.is(1, 1); // true
Object.is(+0, -0); // false
Object.is(NaN, NaN); // true
Object.is(true, "true"); // false
Object.is(false, 0); // false
Object.is(null, undefined); // false
Object.is(1, "1"); // false
Object.is([], []); // false
Dieser Algorithmus hat die Eigenschaften einer Äquivalenzbeziehung :
- Reflexivität :
Object.is(x, x)
ist für jeden Wertx
true
- Symmetrie :
Object.is(x, y)
isttrue
, und nur wennObject.is(y, x)
true
, für alle Wertex
undy
. - Transitivität : Wenn
Object.is(x, y)
undObject.is(y, z)
isttrue
, dannObject.is(x, z)
ist auchtrue
für alle Wertex
,y
undz
.
SameValueZero
Es verhält sich wie SameValue, betrachtet jedoch +0
und -0
als gleich.
Sie können diesen Vergleichsalgorithmus über Array.prototype.includes
(ECMAScript 7) verwenden.
Beispiele:
[1].includes(1); // true
[+0].includes(-0); // true
[NaN].includes(NaN); // true
[true].includes("true"); // false
[false].includes(0); // false
[1].includes("1"); // false
[null].includes(undefined); // false
[[]].includes([]); // false
Dieser Algorithmus hat immer noch die Eigenschaften einer Äquivalenzbeziehung :
- Reflexivität :
[x].includes(x)
isttrue
, für jeden Wertx
- Symmetrie :
[x].includes(y)
isttrue
wenn und nur wenn[y].includes(x)
true
, für alle Wertex
undy
. - Transitivität : Wenn
[x].includes(y)
und[y].includes(z)
isttrue
, dann[x].includes(z)
ist auchtrue
, für alle Wertex
,y
undz
.
Strenger Gleichheitsvergleich
Es verhält sich wie SameValue, aber
- Hält
+0
und-0
für gleich. - Betrachtet
NaN
als einen anderen Wert, einschließlich sich selbst
Sie können diesen Vergleichsalgorithmus über den Operator ===
(ECMAScript 3) verwenden.
Es gibt auch den Operator !==
(ECMAScript 3), der das Ergebnis von ===
negiert.
Beispiele:
1 === 1; // true
+0 === -0; // true
NaN === NaN; // false
true === "true"; // false
false === 0; // false
1 === "1"; // false
null === undefined; // false
[] === []; // false
Dieser Algorithmus hat folgende Eigenschaften:
- Symmetrie :
x === y
isttrue
, wenn und nur dann, wenn y === xis
wahr, for any values
xand
y`. - Transitivität : Wenn
x === y
undy === z
sindtrue
, dannx === z
ist auchtrue
, für alle Wertex
,y
undz
.
Ist aber kein Äquivalenzverhältnis da
-
NaN
ist nicht reflexiv :NaN !== NaN
Abstrakter Vergleich der Gleichheit
Wenn beide Operanden zum selben Typ gehören, verhält es sich wie der Vergleich der strengen Gleichheit.
Ansonsten zwingt sie sie wie folgt:
-
undefined
undnull
werden als gleich betrachtet - Wenn Sie eine Zahl mit einer Zeichenfolge vergleichen, wird die Zeichenfolge in eine Zahl umgewandelt
- Beim Vergleich eines Booleschen Werts mit etwas anderem wird der Boolesche Wert in eine Zahl umgewandelt
- Beim Vergleichen eines Objekts mit einer Zahl, einem String oder einem Symbol wird das Objekt zu einem Primitiv gezwungen
Wenn es einen Zwang gab, werden die erzwungenen Werte rekursiv verglichen. Andernfalls gibt der Algorithmus false
.
Sie können diesen Vergleichsalgorithmus über den Operator ==
(ECMAScript 1) verwenden.
Es gibt auch den Operator !=
(ECMAScript 1), der das Ergebnis von ==
negiert.
Beispiele:
1 == 1; // true
+0 == -0; // true
NaN == NaN; // false
true == "true"; // false
false == 0; // true
1 == "1"; // true
null == undefined; // true
[] == []; // false
Dieser Algorithmus hat die folgende Eigenschaft:
- Symmetrie :
x == y
isttrue
, und nur wenny == x
true
, für alle Wertex
undy
.
Ist aber kein Äquivalenzverhältnis da
-
NaN
ist nicht reflexiv :NaN != NaN
- Transitivität gilt nicht, zB
0 == ''
und0 == '0'
, aber'' != '0'
Mehrere logische Anweisungen gruppieren
Sie können mehrere boolesche Logikanweisungen in Klammern gruppieren, um eine komplexere Logikauswertung zu erstellen, die insbesondere in if-Anweisungen nützlich ist.
if ((age >= 18 && height >= 5.11) || (status === 'royalty' && hasInvitation)) {
console.log('You can enter our club');
}
Wir könnten auch die gruppierte Logik in Variablen verschieben, um die Aussage etwas kürzer und beschreibender zu gestalten:
var isLegal = age >= 18;
var tall = height >= 5.11;
var suitable = isLegal && tall;
var isRoyalty = status === 'royalty';
var specialCase = isRoyalty && hasInvitation;
var canEnterOurBar = suitable || specialCase;
if (canEnterOurBar) console.log('You can enter our club');
Beachten Sie, dass in diesem bestimmten Beispiel (und in vielen anderen) das Gruppieren der Anweisungen mit Klammern genauso funktioniert, als würden wir sie entfernen. Folgen Sie einfach einer linearen Logikauswertung, und Sie erhalten das gleiche Ergebnis. Ich ziehe es vor, Klammern zu verwenden, da ich dadurch klarer verstehen kann, was ich beabsichtige und bei Logikfehlern verhindern könnte.
Automatische Typumwandlungen
Beachten Sie, dass Zahlen versehentlich in Zeichenfolgen oder NaN (Not a Number) umgewandelt werden können.
JavaScript ist lose eingegeben. Eine Variable kann verschiedene Datentypen enthalten, und eine Variable kann ihren Datentyp ändern:
var x = "Hello"; // typeof x is a string
x = 5; // changes typeof x to a number
Bei mathematischen Operationen kann JavaScript Zahlen in Strings konvertieren:
var x = 5 + 7; // x.valueOf() is 12, typeof x is a number
var x = 5 + "7"; // x.valueOf() is 57, typeof x is a string
var x = "5" + 7; // x.valueOf() is 57, typeof x is a string
var x = 5 - 7; // x.valueOf() is -2, typeof x is a number
var x = 5 - "7"; // x.valueOf() is -2, typeof x is a number
var x = "5" - 7; // x.valueOf() is -2, typeof x is a number
var x = 5 - "x"; // x.valueOf() is NaN, typeof x is a number
Beim Abziehen eines Strings von einem String wird kein Fehler generiert, sondern NaN (Not a Number) zurückgegeben:
"Hello" - "Dolly" // returns NaN
Liste der Vergleichsoperatoren
Operator | Vergleich | Beispiel |
---|---|---|
== | Gleich | i == 0 |
=== | Gleicher Wert und Typ | i === "5" |
!= | Nicht gleich | i != 5 |
!== | Nicht gleichwertig oder gleichwertig | i !== 5 |
> | Größer als | i > 5 |
< | Weniger als | i < 5 |
>= | Größer als oder gleich | i >= 5 |
<= | Weniger als oder gleich | i <= 5 |
Bitfelder zur Optimierung des Vergleichs von Multi-State-Daten
Ein Bitfeld ist eine Variable, die verschiedene Boolesche Zustände als einzelne Bits enthält. Ein bisschen an würde wahr sein und aus wäre falsch. In der Vergangenheit wurden Bitfelder routinemäßig verwendet, da sie Speicher sparten und die Verarbeitungslast reduzieren. Obwohl die Verwendung von Bitfeld nicht mehr so wichtig ist, bieten sie einige Vorteile, die viele Verarbeitungsaufgaben vereinfachen können.
Zum Beispiel Benutzereingaben. Wenn Sie die Eingabe über die Richtungstasten einer Tastatur nach oben, unten, links und rechts erhalten, können Sie die verschiedenen Tasten in einer einzigen Variablen codieren, wobei jeder Richtung ein Bit zugewiesen wird.
Beispiel für das Lesen der Tastatur über Bitfield
var bitField = 0; // the value to hold the bits
const KEY_BITS = [4,1,8,2]; // left up right down
const KEY_MASKS = [0b1011,0b1110,0b0111,0b1101]; // left up right down
window.onkeydown = window.onkeyup = function (e) {
if(e.keyCode >= 37 && e.keyCode <41){
if(e.type === "keydown"){
bitField |= KEY_BITS[e.keyCode - 37];
}else{
bitField &= KEY_MASKS[e.keyCode - 37];
}
}
}
Beispiel lesen als Array
var directionState = [false,false,false,false];
window.onkeydown = window.onkeyup = function (e) {
if(e.keyCode >= 37 && e.keyCode <41){
directionState[e.keyCode - 37] = e.type === "keydown";
}
}
Um etwas zu aktivieren, verwenden Sie bitweise oder |
und der dem Bit entsprechende Wert. Wenn Sie also das 2. Bit bitField |= 0b10
wird bitField |= 0b10
. Wenn Sie ein bisschen ausschalten möchten, verwenden Sie bitweise und &
mit einem Wert, der alle erforderlichen Bits enthält. Verwenden von 4 Bits und bitfield &= 0b1101;
des 2. Bits des bitfield &= 0b1101;
Sie können sagen, dass das obige Beispiel viel komplexer erscheint als die Zuweisung der verschiedenen Schlüsselzustände zu einem Array. Ja Die Einstellung ist etwas komplexer, aber der Vorteil ergibt sich, wenn der Staat abgefragt wird.
Wenn Sie testen möchten, ob alle Tasten belegt sind.
// as bit field
if(!bitfield) // no keys are on
// as array test each item in array
if(!(directionState[0] && directionState[1] && directionState[2] && directionState[3])){
Sie können einige Konstanten festlegen, um die Arbeit zu erleichtern
// postfix U,D,L,R for Up down left right
const KEY_U = 1;
const KEY_D = 2;
const KEY_L = 4;
const KEY_R = 8;
const KEY_UL = KEY_U + KEY_L; // up left
const KEY_UR = KEY_U + KEY_R; // up Right
const KEY_DL = KEY_D + KEY_L; // down left
const KEY_DR = KEY_D + KEY_R; // down right
Sie können dann schnell verschiedene Tastaturzustände testen
if ((bitfield & KEY_UL) === KEY_UL) { // is UP and LEFT only down
if (bitfield & KEY_UL) { // is Up left down
if ((bitfield & KEY_U) === KEY_U) { // is Up only down
if (bitfield & KEY_U) { // is Up down (any other key may be down)
if (!(bitfield & KEY_U)) { // is Up up (any other key may be down)
if (!bitfield ) { // no keys are down
if (bitfield ) { // any one or more keys are down
Die Tastatureingabe ist nur ein Beispiel. Bitfelder sind nützlich, wenn Sie verschiedene Zustände haben, auf die in Kombination eingegangen werden muss. Javascript kann bis zu 32 Bit für ein Bitfeld verwenden. Ihre Verwendung kann zu erheblichen Leistungssteigerungen führen. Sie sind es wert, mit ihnen vertraut zu sein.