Sök…


Anmärkningar

Vid användning av booleskt tvång betraktas följande värden "falskt" :

  • false
  • 0
  • "" (tom sträng)
  • null
  • undefined
  • NaN (inte ett nummer, t.ex. 0/0 )
  • document.all ¹ (webbläsarsammanhang)

Allt annat betraktas som "sanningen" .

¹ avsiktlig överträdelse av ECMAScript-specifikationen

Logikoperatörer med booléer

var x = true,
    y = false;

OCH

Denna operatör kommer att returnera sant om båda uttryck utvärderas till sant. Denna booleska operatör kommer att använda kortslutning och kommer inte att utvärdera y om x utvärderas till false .

x && y;

Detta kommer att returnera falskt, eftersom y är falskt.

ELLER

Denna operatör kommer att returnera sant om ett av de två uttryck utvärderar till sant. Denna booleska operatör kommer att använda kortslutning och y kommer inte att utvärderas om x utvärderas till true .

x || y;

Detta kommer att återkomma, eftersom x är sant.

INTE

Denna operatör kommer att returnera falskt om uttrycket till höger utvärderar till sant, och returnerar sant om uttrycket till höger utvärderar till falskt.

!x;

Detta kommer att returnera falskt, eftersom x är sant.

Abstrakt jämställdhet (==)

Operanterna för operatören för abstrakt jämlikhet jämförs efter att de har konverterats till en vanlig typ. Hur denna konvertering sker baseras på specifikationen för operatören:

Specifikation för operatören == :

7.2.13 Abstrakt jämställdhetsjämförelse

Jämförelsen x == y , där x och y är värden, ger true eller false . En sådan jämförelse utförs enligt följande:

  1. Om Type(x) är samma som Type(y) , gör så:
  • a. Returnera resultatet av att utföra Strict Equality Comparison x === y .
  1. Om x är null och y är undefined , returnera true .
  2. Om x är undefined och y är null , returnera true .
  3. Om Type(x) är Number och Type(y) är String , returnerar resultatet av jämförelsen x == ToNumber(y) .
  4. Om Type(x) är String och Type(y) är Number , returnera resultatet av jämförelsen ToNumber(x) == y .
  5. Om Type(x) är Boolean , returnerar du resultatet av jämförelsen ToNumber(x) == y .
  6. Om Type(y) är Boolean , returnerar du resultatet av comparison x == ToNumber(y) .
  7. Om Type(x) antingen är String , Number eller Symbol och Type(y) är Object , returnerar resultatet av jämförelsen x == ToPrimitive(y) .
  8. Om Type(x) är Objekt och Type(y) är antingen String , Number eller Symbol , returnerar resultatet av jämförelsen ToPrimitive(x) == y .
  9. Returnera false .

Exempel:

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

Relationsoperatörer (<, <=,>,> =)

När båda operanderna är numeriska jämförs de normalt:

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

När båda operanderna är strängar jämförs de lexikografiskt (enligt alfabetisk ordning):

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

När en operand är en sträng och den andra är ett nummer konverteras strängen till ett nummer före jämförelse:

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

När strängen är icke-numerisk, returnerar numerisk konvertering NaN (inte-ett-nummer). Jämförelse med NaN returnerar alltid false :

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

Men var försiktig när du jämför ett numeriskt värde med null , undefined eller tomma strängar:

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

När en operand är ett objekt och den andra är ett nummer konverteras objektet till ett nummer före jämförelse. null är särskilt fall eftersom Number(null);//0

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

Olikhet

Operatör != Är invers från operatören == .
Kommer tillbaka true om operanderna är inte lika.
Javascript-motorn kommer att försöka konvertera båda operanderna till matchande typer om de inte är av samma typ. Obs: Om de två operandema har olika interna referenser i minnet, kommer false att returneras.

Prov:

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

I exemplet ovan är 1 != '1' false eftersom en primitiv siffertyp jämförs med ett char värde. Därför bryr inte Javascript-motorn sig om datatypen för RHS-värdet.

Operatör !== är invers från operatören === . Kommer tillbaka om operandarna inte är lika eller om deras typer inte matchar.

Exempel:

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

Logikoperatörer med icke-booleska värden (booleskt tvång)

Logiskt ELLER ( || ), som läser från vänster till höger, kommer att utvärdera till det första sanningsvärdet . Om inget sanningsvärde hittas returneras det sista värdet.

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'

Logiskt OCH ( && ), läsning från vänster till höger, kommer att utvärdera till det första falska värdet. Om inget falsey- värde hittas, returneras det sista värdet.

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

Detta trick kan till exempel användas för att ställa in ett standardvärde till ett funktionsargument (före 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

Tänk bara på att för argument, 0 och (i mindre utsträckning) är den tomma strängen ofta giltiga värden som borde kunna passeras uttryckligen och åsidosätta ett standard, som de med detta mönster inte kommer att göra (eftersom de är falsk ).

Null och odefinierad

Skillnaderna mellan null och undefined

null och undefined dela abstrakt jämlikhet == men inte strikt jämlikhet === ,

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

De representerar något olika saker:

  • undefined representerar frånvaron av ett värde , till exempel innan en identifierare / Objektegenskap har skapats eller under perioden mellan skapande av identifierare / Funktionsparametrar och dess första inställning, om någon.
  • null representerar avsiktlig frånvaro av ett värde för en identifierare eller egendom som redan har skapats.

De är olika typer av syntax:

  • undefined är en egenskap hos det globala objektet , vanligtvis oföränderligt i det globala omfånget. Detta betyder att var som helst du kan definiera att en annan identifierare än i det globala namnområdet kan dölja undefined från det räckvidden (även om saker fortfarande kan undefined )
  • null är ett ord bokstavligt , så det innebär att det aldrig kan ändras och att försöka göra det kommer att kasta ett fel .

Likheterna mellan null och undefined

null och undefined är båda falska.

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

Varken null eller undefined lika false (se denna fråga ).

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

Använda undefined

  • Om det nuvarande räckvidden inte kan lita på, använd något som utvärderar till odefinierat , till exempel void 0; .
  • Om undefined är skuggad av ett annat värde, är det lika dåligt som att skugga Array eller Number .
  • Undvik att ställa in något som undefined . Om du vill ta bort en fastighet bar från ett objekt foo , delete foo.bar; istället.
  • Existentest-identifierare foo mot undefined kan kasta ett referensfel , använd typeof foo mot "undefined" istället.

Det globala objektets NaN-egendom

NaN (" N ot a N umber") är ett specialvärde som definieras av IEEE-standarden för flytande punkt aritmetik , som används när ett icke-numeriskt värde tillhandahålls men ett tal förväntas ( 1 * "two" ), eller när en beräkning inte har ett giltigt number resultat ( Math.sqrt(-1) ).

Varje jämlikhet eller relationella jämförelser med NaN returnerar false , till och med att jämföra det med sig själv. Eftersom NaN är tänkt att beteckna resultatet av en nonsensical beräkning, och som sådan är det inte lika med resultatet av andra nonsensical beräkningar.

(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

Icke-lika jämförelser kommer alltid att true :

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

Kontrollera om ett värde är NaN

6

Du kan testa ett värde eller ett uttryck för NaN med hjälp av funktionen 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

Du kan kontrollera om ett värde är NaN genom att jämföra det med sig själv:

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

Du kan använda följande polyfill för Number.isNaN() :

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

Däremot den globala funktionen isNaN() returnerar true inte bara för NaN , utan även för något värde eller uttryck som inte kan tvingas in i ett antal:

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 definierar en "likhet" SameValue som heter SameValue som sedan ECMAScript 6 kan åberopas med Object.is . Till skillnad === jämförelsen == och === , kommer Object.is() att behandla NaN som identisk med sig själv (och -0 som inte identisk med +0 ):

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

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

Du kan använda följande polyfill för Object.is() (från 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;
    }
  };
}

Poäng att notera

NaN själv är ett tal, vilket betyder att det inte är lika med strängen "NaN", och viktigast av allt (men kanske oinitivt):

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

Kortslutning hos booleska operatörer

Operatören ( && ) och operatören ( || ) använder kortslutning för att förhindra onödigt arbete om resultatet av operationen inte förändras med extraarbetet.

I x && y kommer y inte att utvärderas om x utvärderas till false , eftersom hela uttrycket garanteras vara false .

I x || y , y kommer inte att utvärderas om x utvärderas till true , eftersom hela uttrycket garanteras vara true .

Exempel med funktioner

Ta följande två funktioner:

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

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

Exempel 1

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

Produktion:

'T'
'F'

Exempel 2

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

Produktion:

'F'

Exempel 3

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

Produktion:

'T'

Exempel 4

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

Produktion:

'F'
'T'


Kortslutning för att förhindra fel

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

Rad A: om du vänder ordningen kommer det första villkorade uttalandet att förhindra felet på det andra genom att inte utföra det om det skulle kasta felet

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

Men bör endast användas om du förväntar dig undefined

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

Kortslutning för att ge ett standardvärde

Den || operatören kan användas för att välja antingen ett "sanningsvärde" eller standardvärdet.

Till exempel kan detta användas för att säkerställa att ett nullable värde konverteras till ett icke nullable värde:

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

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

Eller för att returnera det första sanningsvärdet

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

Samma kan användas för att falla tillbaka flera gånger:

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

Kortslutning för att ringa en valfri funktion

Operatören && kan användas för att utvärdera ett återuppringning, bara om det skickas:

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

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

Naturligtvis validerar testet ovan inte att cb faktiskt är en function och inte bara ett Object / Array / String / Number .

Abstrakt jämlikhet / ojämlikhet och typkonvertering

Problemet

Operatörerna för abstrakt jämlikhet och ojämlikhet ( == och != ) Konverterar sina operander om operandtyperna inte matchar. Denna typ av tvång är en vanlig källa till förvirring kring resultaten från dessa operatörer, särskilt dessa operatörer är inte alltid övergående som man kan förvänta sig.

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

Resultaten börjar vara meningsfulla om du funderar på hur JavaScript konverterar tomma strängar till siffror.

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

Lösningen

I uttalandet false B är båda operanderna strängar ( "" och "0" ), därför kommer det inte att finnas någon typkonvertering och eftersom "" och "0" inte är samma värde, "" == "0" är false som förväntat.

Ett sätt att eliminera oväntat beteende här är att se till att du alltid jämför operander av samma typ. Om du till exempel vill ha resultat från numerisk jämförelse använder du explicerad konvertering:

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 

Eller om du vill jämföra sträng:

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

Sidnot : Number("0") och new Number("0") är inte samma sak! Medan den förstnämnda utför en typkonvertering kommer den senare att skapa ett nytt objekt. Objekt jämförs med referens och inte med värde vilket förklarar resultaten nedan.

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

Slutligen har du möjlighet att använda strikta jämställdhets- och ojämlikhetsoperatörer som inte kommer att utföra några implicita typkonverteringar.

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

Mer information om detta ämne finns här:

Vilka är lika med operatören (== vs ===) som ska användas i JavaScript-jämförelser? .

Abstrakt jämställdhet (==)

Tom Array

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

När [].toString() körs ringer det [].join() om det finns, eller Object.prototype.toString() annars. Denna jämförelse återgår true eftersom [].join() returnerar '' som tvingas till 0 är lika med falskt ToNumber .

Akta dig dock, alla objekt är sanningsenliga och Array är ett exempel på Object :

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

Jämställdhetsjämförelse

JavaScript har fyra olika jämställdhetsjämförelser.

SameValue

Det returnerar true om båda operanderna tillhör samma typ och har samma värde.

Obs: värdet på ett objekt är en referens.

Du kan använda denna jämförelsealgoritm via Object.is (ECMAScript 6).

Exempel:

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

Denna algoritm har egenskaperna för en ekvivalensrelation :

  • Reflexivitet : Object.is(x, x) är true , för alla värden x
  • Symmetri : Object.is(x, y) är true om, och endast om Object.is(y, x) är true , för alla värden x och y .
  • Transitivitet : Om Object.is(x, y) och Object.is(y, z) är true , är Object.is(x, z) också true , för alla värden x , y och z .

SameValueZero

Det uppför sig som SameValue, men anser att +0 och -0 är lika.

Du kan använda denna jämförelsealgoritm via Array.prototype.includes (ECMAScript 7).

Exempel:

[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

Denna algoritm har fortfarande egenskaperna för en ekvivalensrelation :

  • Reflexivitet : [x].includes(x) är true , för alla värden x
  • Symmetri : [x].includes(y) är true om, och endast om, [y].includes(x) är true , för alla värden x och y .
  • Transitivitet : Om [x].includes(y) och [y].includes(z) är true , är [x].includes(z) också true , för alla värden x , y och z .

Strikt jämställdhetsjämförelse

Det uppför sig som SameValue, men

  • Anser att +0 och -0 ska vara lika.
  • Anser att NaN annorlunda än något värde, inklusive sig själv

Du kan använda denna jämförelsealgoritm via === operatören (ECMAScript 3).

Det finns också !== operatören (ECMAScript 3), som förnekar resultatet av === .

Exempel:

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

Denna algoritm har följande egenskaper:

  • Symmetri : x === y är true om, och bara om, y === x is sant , for any values x and y`.
  • Transitivitet : Om x === y och y === z är true , är x === z också true , för alla värden x , y och z .

Men är inte en ekvivalensrelation för

Abstrakt jämställdhetsjämförelse

Om båda operanderna tillhör samma typ, uppträder det som Strict Equality Comparison.

Annars tvingar det dem enligt följande:

  • undefined och null anses vara lika
  • När man jämför ett nummer med en sträng, tvingas strängen till ett nummer
  • När man jämför en boolean med något annat, tvingas den boolesiska till ett tal
  • När man jämför ett objekt med ett nummer, sträng eller symbol tvingas objektet till en primitiv

Om det var tvång, jämförs de tvingade värdena rekursivt. Annars returnerar algoritmen false .

Du kan använda denna jämförelsealgoritm via == operatören (ECMAScript 1).

Det finns också != Operatören (ECMAScript 1), som förnekar resultatet av == .

Exempel:

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

Denna algoritm har följande egenskap:

  • Symmetri : x == y är true om, och bara om, y == x är true , för alla värden x och y .

Men är inte en ekvivalensrelation för

Gruppera flera logiska uttalanden

Du kan gruppera flera booleska logiska uttalanden inom parentes för att skapa en mer komplex logisk utvärdering, särskilt användbar om uttalanden.

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

Vi kan också flytta den grupperade logiken till variabler för att göra uttalandet lite kortare och beskrivande:

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

Lägg märke till att i det här exemplet (och många andra), gruppering av uttalanden med parentes fungerar på samma sätt som om vi tog bort dem, följ bara en linjär logisk utvärdering så hittar du dig själv med samma resultat. Jag föredrar att använda parenteser eftersom det gör att jag kan förstå tydligare vad jag tänkte och kan förhindra för logiska misstag.

Automatiska typkonverteringar

Se upp för att oavsiktligt kan konverteras till strängar eller NaN (Inte ett nummer).

JavaScript skrivs löst. En variabel kan innehålla olika datatyper och en variabel kan ändra dess datatyp:

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

När du gör matematiska operationer kan JavaScript konvertera nummer till strängar:

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

Att subtrahera en sträng från en sträng genererar inte ett fel utan returnerar NaN (inte ett nummer):

"Hello" - "Dolly"    // returns NaN

Lista över jämförande operatörer

Operatör Jämförelse Exempel
== Likvärdig i == 0
=== Lika värde och typ i === "5"
!= Inte jämnlikt i != 5
!== Inte lika värde eller typ i !== 5
> Större än i > 5
< Mindre än i < 5
>= Större än eller lika med i >= 5
<= Mindre än eller lika i <= 5

Bitfält för att optimera jämförelsen av multi-state-data

Ett bitfält är en variabel som innehåller olika booleska tillstånd som enskilda bitar. Lite på skulle representera sant och av skulle vara falskt. Tidigare användes bitfält rutinmässigt eftersom de sparade minne och minskade behandlingsbelastning. Även om behovet av att använda bitfält inte längre är så viktigt erbjuder de vissa fördelar som kan förenkla många behandlingsuppgifter.

Till exempel användarinmatning. När du får input från ett tangentbords riktningstangenter upp, ner, vänster, höger kan du koda de olika tangenterna till en enda variabel med varje riktning tilldelad en bit.

Exempel på läsningstangentbord via bitfält

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

Exempelläsning som en matris

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

För att slå på lite använder du bitvis eller | och värdet som motsvarar biten. Så om du vill ställa in den andra biten bitField |= 0b10 slår den på. Om du vill stänga av lite använder du bitvis och & med ett värde som har alla med den önskade biten på. Använda 4 bitar och stänga av den andra biten från bitfield &= 0b1101;

Du kan säga att exemplet ovan verkar mycket mer komplicerat än att tilldela olika nyckeltillstånd till en matris. Ja Det är lite mer komplicerat att ställa in, men fördelen kommer när man förhör staten.

Om du vill testa om alla knappar är uppe.

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

Du kan ställa in några konstanter för att göra det lättare

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

Du kan sedan snabbt testa för många olika tangentbordstillstånd

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

Tangentbordets ingång är bara ett exempel. Bitfält är användbara när du har olika tillstånd som måste kombineras. Javascript kan använda upp till 32 bitar för ett bitfält. Att använda dem kan ge betydande prestationsökningar. De är värda att vara bekanta med.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow