Zoeken…


Opmerkingen

Bij het gebruik van booleaanse dwang worden de volgende waarden als "vals" beschouwd :

  • false
  • 0
  • "" (lege string)
  • null
  • undefined
  • NaN (geen nummer, bijv. 0/0 )
  • document.all ¹ (browser context)

Al het andere wordt als "waarheidsgetrouw" beschouwd .

¹ opzettelijke schending van de ECMAScript-specificatie

Logische operators met Booleans

var x = true,
    y = false;

EN

Deze operator retourneert true als beide expressies de waarde true hebben. Deze booleaanse operator gebruikt kortsluiting en evalueert y als x als false evalueert.

x && y;

Dit zal false retourneren, omdat y false is.

OF

Deze operator retourneert true als een van de twee expressies de waarde true geeft. Deze booleaanse operator gebruikt kortsluiting en y wordt niet geëvalueerd als x naar true evalueert.

x || y;

Dit zal waar terugkeren, omdat x waar is.

NIET

Deze operator retourneert false als de uitdrukking aan de rechterkant als waar evalueert en retourneert true als de uitdrukking aan de rechterkant als onwaar evalueert.

!x;

Dit zal false retourneren, omdat x waar is.

Abstracte gelijkheid (==)

Operanden van de abstracte gelijkheidsoperator worden vergeleken nadat ze zijn geconverteerd naar een gemeenschappelijk type. Hoe deze conversie gebeurt, is gebaseerd op de specificatie van de operator:

Specificatie voor de == operator:

7.2.13 Vergelijking van abstracte gelijkheid

De vergelijking x == y , waarbij x en y waarden zijn, levert true of false . Een dergelijke vergelijking wordt als volgt uitgevoerd:

  1. Als Type(x) hetzelfde is als Type(y) , dan:
  • een. Retourneer het resultaat van het uitvoeren van Strikt Equality Comparison x === y .
  1. Als x null en y is undefined , geeft u true terug.
  2. Als x is undefined en y null , geeft u true terug.
  3. Als Type(x) Number en Type(y) String , retourneert u het resultaat van de vergelijking x == ToNumber(y) .
  4. Als Type(x) String en Type(y) Number , retourneert u het resultaat van de vergelijking ToNumber(x) == y .
  5. Als Type(x) Boolean , retourneert u het resultaat van de vergelijking ToNumber(x) == y .
  6. Als Type(y) Boolean , retourneert u het resultaat van de comparison x == ToNumber(y) .
  7. Als Type(x) String , Number of Symbol en Type(y) Object , retourneert u het resultaat van de vergelijking x == ToPrimitive(y) .
  8. Als Type(x) Object is en Type(y) String , Number of Symbol , retourneert het resultaat van de vergelijking ToPrimitive(x) == y .
  9. Return false .

Voorbeelden:

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

Relationele operatoren (<, <=,>,> =)

Wanneer beide operanden numeriek zijn, worden ze normaal vergeleken:

1 < 2        // true
2 <= 2       // true
3 >= 5       // false
true < false // false (implicitly converted to numbers, 1 > 0)

Wanneer beide operanden strings zijn, worden ze lexicografisch vergeleken (op alfabetische volgorde):

'a' < 'b'    // true
'1' < '2'    // true
'100' > '12' // false ('100' is less than '12' lexicographically!)

Wanneer de ene operand een string is en de andere een getal, wordt de string vóór vergelijking omgezet in een getal:

'1' < 2      // true
'3' > 2      // true
true > '2'   // false (true implicitly converted to number, 1 < 2)

Wanneer de tekenreeks niet-numeriek is, retourneert numerieke conversie NaN (geen nummer). Vergelijken met NaN levert altijd false :

1 < 'abc'    // false
1 > 'abc'    // false

Maar wees voorzichtig bij het vergelijken van een numerieke waarde met null , undefined of lege tekenreeksen:

1 > ''        // true
1 < ''        // false
1 > null      // true
1 < null      // false
1 > undefined // false
1 < undefined // false

Wanneer de ene operand een object is en de andere een getal, wordt het object vóór vergelijking geconverteerd naar een getal. Zo null is in het bijzonder omdat Number(null);//0

new Date(2015)< 1479480185280            // true
null > -1                                //true
({toString:function(){return 123}}) > 122  //true

Ongelijkheid

Operator != Is het omgekeerde van de operator == .
Zal true terugkeren als de operanden niet gelijk zijn.
De JavaScript-engine probeert beide operanden om te zetten in overeenkomende typen als ze niet van hetzelfde type zijn. Opmerking: als de twee operanden verschillende interne referenties in het geheugen hebben, wordt false geretourneerd.

Monster:

1 != '1'     // false
1 != 2       // true

In het bovenstaande voorbeeld is 1 != '1' false omdat een primitief getaltype wordt vergeleken met een char waarde. Daarom geeft de Javascript-engine niet om het gegevenstype van de RHS-waarde.

Operator !== is het omgekeerde van de operator === . Retourneert true als de operanden niet gelijk zijn of als hun typen niet overeenkomen.

Voorbeeld:

1 !== '1'    // true
1 !== 2      // true
1 !== 1      // false

Logische operatoren met niet-booleaanse waarden (booleaanse dwang)

Logisch OF ( || ), van links naar rechts lezen, wordt geëvalueerd naar de eerste waarheidswaarde . Als er geen waarheidswaarde wordt gevonden, wordt de laatste waarde geretourneerd.

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'

Logisch EN ( && ), van links naar rechts lezen, wordt geëvalueerd naar de eerste valse waarde. Als er geen valse waarde wordt gevonden, wordt de laatste waarde geretourneerd.

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

Deze truc kan bijvoorbeeld worden gebruikt om een standaardwaarde in te stellen op een functieargument (voorafgaand aan ES6).

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

Houd er rekening mee dat voor argumenten 0 en (in mindere mate) de lege tekenreeks ook vaak geldige waarden zijn die expliciet moeten kunnen worden doorgegeven en een standaardwaarde overschrijven, wat ze met dit patroon niet doen (omdat ze zijn vals ).

Null en ongedefinieerd

De verschillen tussen null en undefined

null en undefined aandeel abstracte gelijkheid == maar niet strikte gelijkheid === ,

null == undefined   // true
null === undefined  // false

Ze vertegenwoordigen iets verschillende dingen:

  • undefined staat voor de afwezigheid van een waarde , zoals voordat een identifier / objecteigenschap is gemaakt of in de periode tussen het maken van identifier / functieparameters en de eerste set, indien aanwezig.
  • null staat voor de opzettelijke afwezigheid van een waarde voor een ID of eigenschap die al is gemaakt.

Het zijn verschillende soorten syntaxis:

  • undefined is een eigenschap van het globale object , meestal onveranderlijk in het globale bereik. Dit betekent dat overal waar u een ID kunt definiëren, anders dan in de globale naamruimte, undefined kan worden verborgen voor dat bereik (hoewel dingen nog steeds undefined )
  • null is een letterlijk woord , dus de betekenis ervan kan nooit worden gewijzigd en een poging daartoe zal een fout veroorzaken .

De overeenkomsten tussen null en undefined

null en undefined zijn beide vals.

if (null) console.log("won't be logged");
if (undefined) console.log("won't be logged");

null of undefined gelijk aan false (zie deze vraag ).

false == undefined   // false
false == null        // false
false === undefined  // false
false === null       // false

undefined

  • Als het huidige bereik niet kan worden vertrouwd, gebruikt u iets dat als ongedefinieerd wordt geëvalueerd, bijvoorbeeld void 0; .
  • Als undefined wordt overschaduwd door een andere waarde, is het net zo erg als Array of Number overschaduwen.
  • Vermijd het instellen van iets als undefined . Als u een woning wilt bar van een object te verwijderen foo , delete foo.bar; in plaats daarvan.
  • Het bestaan van het testen van identificatie foo tegen undefined kan een referentiefout veroorzaken , in plaats daarvan type typeof foo tegen "undefined" .

NaN Eigendom van het globale object

NaN (" N ot a N umber") is een speciale waarde gedefinieerd door de IEEE-standaard voor drijvende komma-rekenkunde , die wordt gebruikt wanneer een niet-numerieke waarde wordt opgegeven maar een nummer wordt verwacht ( 1 * "two" ), of wanneer een berekening omvat geen geldig number resultaat ( Math.sqrt(-1) ).

Elke gelijkheid of relationele vergelijkingen met NaN retourneert false , zelfs als het wordt vergeleken met zichzelf. Omdat NaN wordt verondersteld het resultaat van een onzinnige berekening aan te geven, en als zodanig is het niet gelijk aan het resultaat van andere onzinnige berekeningen.

(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

Niet-gelijke vergelijkingen zullen altijd true :

NaN !== 0;          // true
NaN !== NaN;        // true

Controleren of een waarde NaN is

6

U kunt een waarde of uitdrukking voor NaN testen met behulp van de functie Number.isNaN () :

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

U kunt controleren of een waarde NaN door deze met zichzelf te vergelijken:

value !== value;    // true for NaN, false for any other value

U kunt de volgende polyfill gebruiken voor Number.isNaN() :

Number.isNaN = Number.isNaN || function(value) {     
    return value !== value;
}

De globale functie isNaN() retourneert true niet alleen voor NaN , maar ook voor elke waarde of expressie die niet in een getal kan worden omgezet:

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 definieert een "gelijkheid" -algoritme genaamd SameValue dat, sinds ECMAScript 6, kan worden opgeroepen met Object.is . In tegenstelling tot de == en === vergelijking, zal het gebruik van Object.is() NaN behandelen als identiek met zichzelf (en -0 als niet identiek met +0 ):

Object.is(NaN, NaN)      // true
Object.is(+0, 0)         // false

NaN === NaN              // false
+0 === 0                 // true
6

U kunt de volgende polyfill gebruiken voor Object.is() (uit MDN ):

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;
    }
  };
}

Punten om op te merken

NaN zelf is een getal, wat betekent dat het niet gelijk is aan de tekenreeks "NaN", en vooral (hoewel misschien niet intuïtief):

typeof(NaN) === "number"; //true

Kortsluiting bij booleaanse operatoren

De en-operator ( && ) en de of-operator ( || ) maken kortsluiting om onnodig werk te voorkomen als de uitkomst van de operatie niet verandert met het extra werk.

In x && y wordt y niet geëvalueerd als x als false evalueert, omdat de hele expressie gegarandeerd false .

In x || y , y wordt niet geëvalueerd als x geëvalueerd als true , omdat de hele expressie gegarandeerd true .

Voorbeeld met functies

Neem de volgende twee functies:

function T() { // True
  console.log("T");
  return true;
}

function F() { // False
  console.log("F");
  return false;
}

voorbeeld 1

T() && F(); // false

Output:

'T'
'F'

Voorbeeld 2

F() && T(); // false

Output:

'F'

Voorbeeld 3

T() || F(); // true

Output:

'T'

Voorbeeld 4

F() || T(); // true

Output:

'F'
'T'


Kortsluiting om fouten te voorkomen

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

Regel A: als u de volgorde omkeert, voorkomt de eerste voorwaardelijke instructie de fout op de tweede door deze niet uit te voeren als de fout zou optreden

if(obj !== undefined && obj.property){}; // no error thrown 

Maar mag alleen worden gebruikt als u undefined verwacht

if(typeof obj === "object" && obj.property){}; // safe option but slower

Kortsluiting om een standaardwaarde te bieden

De || operator kan worden gebruikt om een "waarheidsgetrouwe" waarde of de standaardwaarde te selecteren.

Dit kan bijvoorbeeld worden gebruikt om ervoor te zorgen dat een nulwaarde wordt omgezet in een niet-nulwaarde:

var nullableObj = null;
var obj = nullableObj || {};  // this selects {}

var nullableObj2 = {x: 5};
var obj2 = nullableObj2 || {} // this selects {x: 5}

Of om de eerste waarheidswaarde terug te geven

var truthyValue = {x: 10};
return truthyValue || {}; // will return {x: 10}

Hetzelfde kan worden gebruikt om meerdere keren terug te vallen:

envVariable || configValue || defaultConstValue // select the first "truthy" of these

Kortsluiting om een optionele functie op te roepen

De operator && kan alleen worden gebruikt om een callback te evalueren, als deze wordt doorgegeven:

function myMethod(cb) {
    // This can be simplified
    if (cb) {
       cb();
    }

    // To this
    cb && cb();
}

Natuurlijk bevestigt de bovenstaande test niet dat cb in feite een function en niet alleen een Object / Array / String / Number .

Abstracte gelijkheid / ongelijkheid en typeconversie

Het probleem

De operatoren voor abstracte gelijkheid en ongelijkheid ( == en != ) Converteren hun operanden als de operandtypen niet overeenkomen. Dit type dwang is een veel voorkomende bron van verwarring over de resultaten van deze operatoren, in het bijzonder zijn deze operatoren niet altijd transitief zoals men zou verwachten.

"" ==  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

De resultaten beginnen zinvol te worden als u bedenkt hoe JavaScript lege tekenreeksen omzet in getallen.

Number("");    // 0
Number("0");   // 0
Number(false); // 0

De oplossing

In de instructie false B zijn beide operanden strings ( "" en "0" ), dus er is geen typeconversie en omdat "" en "0" niet dezelfde waarde hebben, "" == "0" is false zoals verwacht.

Een manier om hier onverwacht gedrag te elimineren, is ervoor te zorgen dat u altijd operanden van hetzelfde type vergelijkt. Als u bijvoorbeeld de resultaten van een numerieke vergelijking wilt, gebruik dan expliciete conversie:

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 

Of, als u stringvergelijking wilt:

var test = (a,b) => String(a) == String(b);
test("", 0);   // false;
test("0", 0);  // true
test("", "0"); // false;

Kanttekening : Number("0") en new Number("0") zijn niet hetzelfde! Terwijl de eerste een typeconversie uitvoert, maakt de laatste een nieuw object. Objecten worden vergeleken op basis van referentie en niet op waarde, wat de onderstaande resultaten verklaart.

Number("0") == Number("0");         // true;
new Number("0") == new Number("0"); // false 

Ten slotte hebt u de optie om strikte gelijkheids- en ongelijkheidsexploitanten te gebruiken die geen impliciete type conversies uitvoeren.

"" ===  0;  // false
 0 === "0"; // false
"" === "0"; // false

Verdere verwijzing naar dit onderwerp vindt u hier:

Welke operator (== versus ===) moet worden gebruikt in JavaScript-vergelijkingen? .

Abstracte gelijkheid (==)

Lege array

/* ToNumber(ToPrimitive([])) == ToNumber(false) */
[] == false; // true

Wanneer [].toString() wordt uitgevoerd, roept het [].join() als het bestaat, of anders Object.prototype.toString() . Deze vergelijking wordt true [].join() omdat [].join() retourneert '' dat, gedwongen tot 0 , gelijk is aan false ToNumber .

Maar pas op, alle objecten zijn waarheidsgetrouw en Array is een instantie van Object :

// Internally this is evaluated as ToBoolean([]) === true ? 'truthy' : 'falsy'
[] ? 'truthy' : 'falsy'; // 'truthy'

Gelijkheidsvergelijkingsoperaties

JavaScript heeft vier verschillende gelijkheidsvergelijkingen.

SameValue

Het retourneert true als beide operanden tot hetzelfde type behoren en dezelfde waarde hebben.

Opmerking: de waarde van een object is een referentie.

U kunt dit vergelijkingsalgoritme gebruiken via Object.is (ECMAScript 6).

Voorbeelden:

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

Dit algoritme heeft de eigenschappen van een equivalentierelatie :

  • Reflexiviteit : Object.is(x, x) is true , voor elke waarde x
  • Symmetrie : Object.is(x, y) is true als en alleen als Object.is(y, x) true is voor alle waarden x en y .
  • Overgang : Als Object.is(x, y) en Object.is(y, z) true , is Object.is(x, z) ook true , voor alle waarden x , y en z .

SameValueZero

Het gedraagt zich als SameValue, maar beschouwt +0 en -0 als gelijk.

U kunt dit vergelijkingsalgoritme gebruiken via Array.prototype.includes (ECMAScript 7).

Voorbeelden:

[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

Dit algoritme heeft nog steeds de eigenschappen van een equivalentierelatie :

  • Reflexiviteit : [x].includes(x) is true , voor elke waarde x
  • Symmetrie : [x].includes(y) is true als, en alleen als, [y].includes(x) true , voor alle waarden x en y .
  • Transitiviteit : als [x].includes(y) en [y].includes(z) is true , dan [x].includes(z) ook true voor alle waarden x , y en z .

Strikte gelijkheidsvergelijking

Het gedraagt zich als SameValue, maar

  • Beschouwt +0 en -0 als gelijk.
  • Beschouwt NaN anders dan elke waarde, inclusief zichzelf

U kunt dit vergelijkingsalgoritme gebruiken via de operator === (ECMAScript 3).

Er is ook de operator !== (ECMAScript 3), die het resultaat van === .

Voorbeelden:

1 === 1;            // true
+0 === -0;          // true
NaN === NaN;        // false
true === "true";    // false
false === 0;        // false
1 === "1";          // false
null === undefined; // false
[] === [];          // false

Dit algoritme heeft de volgende eigenschappen:

  • Symmetrie : x === y is true als en alleen als, y === x is waar , for any values x and y`.
  • Overgevoeligheid : Als x === y en y === z true , dan is x === z ook true , voor alle waarden x , y en z .

Maar is geen gelijkwaardigheidsrelatie omdat

Abstracte gelijkheidsvergelijking

Als beide operanden tot hetzelfde type behoren, gedraagt het zich als de vergelijking voor strikte gelijkheid.

Anders worden ze als volgt gedwongen:

  • undefined en null worden als gelijk beschouwd
  • Bij het vergelijken van een nummer met een string, wordt de string gedwongen tot een nummer
  • Bij het vergelijken van een Boolean met iets anders, wordt de Boolean gedwongen tot een getal
  • Bij het vergelijken van een object met een nummer, string of symbool, wordt het object gedwongen tot een primitief

Als er een dwang was, worden de gedwongen waarden recursief vergeleken. Anders retourneert het algoritme false .

U kunt dit vergelijkingsalgoritme gebruiken via de operator == (ECMAScript 1).

Er is ook de operator != (ECMAScript 1), die het resultaat van == .

Voorbeelden:

1 == 1;            // true
+0 == -0;          // true
NaN == NaN;        // false
true == "true";    // false
false == 0;        // true
1 == "1";          // true
null == undefined; // true
[] == [];          // false

Dit algoritme heeft de volgende eigenschap:

  • Symmetrie : x == y is true als en alleen als y == x true is voor alle waarden x en y .

Maar is geen gelijkwaardigheidsrelatie omdat

Meerdere logische verklaringen groeperen

U kunt meerdere booleaanse logische instructies tussen haakjes groeperen om een complexere logische evaluatie te maken, vooral handig in if-instructies.

if ((age >= 18 && height >= 5.11) || (status === 'royalty' && hasInvitation)) {
  console.log('You can enter our club');
}

We kunnen de gegroepeerde logica ook naar variabelen verplaatsen om de instructie een beetje korter en beschrijvend te maken:

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');

Merk op dat in dit specifieke voorbeeld (en vele anderen) het groeperen van de uitspraken tussen haakjes hetzelfde werkt alsof we ze hebben verwijderd, volg gewoon een lineaire logische evaluatie en je zult merken dat je hetzelfde resultaat hebt. Ik gebruik liever haakjes, omdat ik hierdoor beter begrijp wat ik bedoelde en wat logische fouten kan voorkomen.

Automatische typeconversies

Houd er rekening mee dat nummers per ongeluk kunnen worden omgezet in tekenreeksen of NaN (geen nummer).

JavaScript is losjes getypt. Een variabele kan verschillende gegevenstypen bevatten en een variabele kan het gegevenstype wijzigen:

var x = "Hello";     // typeof x is a string
x = 5;               // changes typeof x to a number

Bij wiskundige bewerkingen kan JavaScript getallen omzetten in tekenreeksen:

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

Een tekenreeks aftrekken van een tekenreeks genereert geen fout maar retourneert NaN (geen nummer):

"Hello" - "Dolly"    // returns NaN

Lijst van vergelijkingsoperatoren

operator Vergelijking Voorbeeld
== Gelijk i == 0
=== Gelijke waarde en type i === "5"
!= Niet gelijk i != 5
!== Niet gelijk aan waarde of type i !== 5
> Groter dan i > 5
< Minder dan i < 5
>= Groter dan of gelijk aan i >= 5
<= Minder dan of gelijk i <= 5

Bitvelden om de vergelijking van gegevens met meerdere statussen te optimaliseren

Een bitveld is een variabele die verschillende Booleaanse toestanden als afzonderlijke bits bevat. Een beetje aan zou waar zijn, en uit zou onwaar zijn. In het verleden werden bitvelden routinematig gebruikt omdat ze geheugen bespaarden en de verwerkingsbelasting verminderde. Hoewel de noodzaak om bitveld te gebruiken niet langer zo belangrijk is, bieden ze wel enkele voordelen die veel verwerkingstaken kunnen vereenvoudigen.

Bijvoorbeeld gebruikersinvoer. Wanneer u invoer krijgt van de richtingstoetsen van een toetsenbord omhoog, omlaag, links, rechts, kunt u de verschillende toetsen coderen in een enkele variabele, waarbij elke richting een beetje wordt toegewezen.

Voorbeeld van een toetsenbord lezen via 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];
        }
    }    
}

Voorbeeld lezen als een 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";
    }    
}

Gebruik bitwise of | om een beetje in te schakelen en de waarde die overeenkomt met het bit. Dus als u het 2e bit bitField |= 0b10 wilt bitField |= 0b10 wordt het ingeschakeld. Als je een beetje wilt uitschakelen, gebruik dan bitgewijs en & met een waarde die alles met de vereiste bit aan heeft. Gebruik 4 bits en bitfield &= 0b1101; het 2e bit uit bitfield &= 0b1101;

Je zou kunnen zeggen dat het bovenstaande voorbeeld een stuk ingewikkelder lijkt dan het toewijzen van de verschillende sleuteltoestanden aan een array. Ja, het is een beetje ingewikkelder om in te stellen, maar het voordeel komt bij het ondervragen van de staat.

Als u wilt testen of alle toetsen omhoog zijn.

// 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])){

Je kunt enkele constanten instellen om dingen gemakkelijker te maken

// 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

U kunt dan snel testen voor veel verschillende toetsenbordstatussen

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

De toetsenbordinvoer is slechts één voorbeeld. Bitvelden zijn handig wanneer u verschillende toestanden hebt die in combinatie moeten worden uitgevoerd. Javascript kan tot 32 bits gebruiken voor een bitveld. Het gebruik ervan kan aanzienlijke prestatieverbeteringen bieden. Ze zijn het waard om bekend mee te zijn.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow