Suche…


Bemerkungen

Bei der Verwendung von booleschem Zwang gelten die folgenden Werte als "Fälschung" :

  • false
  • 0
  • "" (leere Zeichenfolge)
  • null
  • undefined
  • NaN (keine Zahl, zB 0/0 )
  • document.all ¹ (Browserkontext)

Alles andere gilt als "wahr" .

¹ vorsätzlicher Verstoß gegen die ECMAScript-Spezifikation

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 Vergleich x == y , wobei x und y Werte sind, erzeugt true oder false . Ein solcher Vergleich wird wie folgt durchgeführt:

  1. Wenn Type(x) mit Type(y) identisch ist, gilt Folgendes:
  • ein. x === y das Ergebnis des strengen Gleichheitsvergleichs x === y .
  1. Wenn x null und y undefined , geben Sie true .
  2. Wenn x undefined und y null , geben Sie true .
  3. Wenn Type(x) Number und Type(y) String , geben Sie das Ergebnis des Vergleichs zurück. x == ToNumber(y) .
  4. Wenn Type(x) String und Type(y) Number , geben Sie das Ergebnis des Vergleichs ToNumber(x) == y .
  5. Wenn Type(x) Boolean , geben Sie das Ergebnis des Vergleichs ToNumber(x) == y .
  6. Wenn Type(y) Boolean , geben Sie das Ergebnis des comparison x == ToNumber(y) .
  7. Wenn Type(x) entweder String , Number oder Symbol und Type(y) Object , geben Sie das Ergebnis des Vergleichs zurück. x == ToPrimitive(y) .
  8. Wenn Type(x) Objekt und Type(y) entweder String , Number oder Symbol , geben Sie das Ergebnis des Vergleichs an ToPrimitive(x) == y .
  9. 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 noch undefined ).
  • 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 von Array oder Number .
  • Vermeiden Sie , etwas als undefined . Wenn Sie eine Immobilie bar aus einem Objekt entfernen möchten foo , delete foo.bar; stattdessen.
  • Der Bestätigungs-Identifier foo gegen undefined könnte einen Referenzfehler auslösen , stattdessen typeof 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

6

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
6

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
6

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? .

Abstrakte Gleichheit (==)

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 Wert x true
  • Symmetrie : Object.is(x, y) ist true , und nur wenn Object.is(y, x) true , für alle Werte x und y .
  • Transitivität : Wenn Object.is(x, y) und Object.is(y, z) ist true , dann Object.is(x, z) ist auch true für alle Werte x , y und z .

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) ist true , für jeden Wert x
  • Symmetrie : [x].includes(y) ist true wenn und nur wenn [y].includes(x) true , für alle Werte x und y .
  • Transitivität : Wenn [x].includes(y) und [y].includes(z) ist true , dann [x].includes(z) ist auch true , für alle Werte x , y und z .

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 ist true , wenn und nur dann, wenn y === x is wahr , for any values x and y`.
  • Transitivität : Wenn x === y und y === z sind true , dann x === z ist auch true , für alle Werte x , y und z .

Ist aber kein Äquivalenzverhältnis da

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 und null 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 ist true , und nur wenn y == x true , für alle Werte x und y .

Ist aber kein Äquivalenzverhältnis da

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.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow