Recherche…
Remarques
Lorsque vous utilisez une coercition, les valeurs suivantes sont considérées comme "falsy" :
-
false
-
0
-
""
(chaîne vide) -
null
-
undefined
-
NaN
(pas un nombre, par exemple0/0
) -
document.all
¹ (contexte du navigateur)
Tout le reste est considéré comme "véridique" .
Opérateurs logiques avec des booléens
var x = true,
y = false;
ET
Cet opérateur renverra true si les deux expressions ont la valeur true. Cet opérateur booléen utilisera un court-circuit et n'évaluera pas y
si x
évalué comme false
.
x && y;
Cela retournera faux, car y
est faux.
OU
Cet opérateur renverra true si l'une des deux expressions a la valeur true. Cet opérateur booléen utilisera la mise en court-circuit et y
ne sera pas évalué si x
évalué à true
.
x || y;
Cela retournera vrai, car x
est vrai.
NE PAS
Cet opérateur renverra false si l'expression à droite est évaluée à true et renvoie true si l'expression à droite est fausse.
!x;
Cela retournera false, car x
est vrai.
Égalité abstraite (==)
Les opérandes de l'opérateur d'égalité abstraite sont comparés après avoir été convertis en un type commun. Comment cette conversion se produit est basée sur les spécifications de l'opérateur:
Spécification pour l'opérateur ==
:
7.2.13 Comparaison d'égalité abstraite
La comparaisonx == y
, oùx
ety
sont des valeurs, produittrue
oufalse
. Une telle comparaison est effectuée comme suit:
- Si
Type(x)
est identique àType(y)
, alors:
- une. Renvoie le résultat de l'exécution de Strict Equality Comparison
x === y
.
- Si
x
estnull
et quey
estundefined
, retourneztrue
.- Si
x
n'estundefined
et quey
estnull
, retourneztrue
.- Si
Type(x)
estNumber
etType(y)
estString
, retournez le résultat de la comparaisonx == ToNumber(y)
.- Si
Type(x)
estString
etType(y)
estNumber
, retournez le résultat de la comparaisonToNumber(x) == y
.- Si
Type(x)
estBoolean
, retournez le résultat de la comparaisonToNumber(x) == y
.- Si
Type(y)
estBoolean
, retournez le résultat de lacomparison x == ToNumber(y)
.- Si
Type(x)
est soitString
,Number
, ouSymbol
etType(y)
estObject
, renvoyez le résultat de la comparaisonx == ToPrimitive(y)
.- Si
Type(x)
est Object etType(y)
estString
,Number
ouSymbol
, renvoyez le résultat de la comparaisonToPrimitive(x) == y
.- Retourne
false
.
Exemples:
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
Opérateurs relationnels (<, <=,>,> =)
Lorsque les deux opérandes sont numériques, ils sont comparés normalement:
1 < 2 // true
2 <= 2 // true
3 >= 5 // false
true < false // false (implicitly converted to numbers, 1 > 0)
Lorsque les deux opérandes sont des chaînes, elles sont comparées lexicographiquement (selon l’ordre alphabétique):
'a' < 'b' // true
'1' < '2' // true
'100' > '12' // false ('100' is less than '12' lexicographically!)
Lorsqu'une opérande est une chaîne et que l'autre est un nombre, la chaîne est convertie en nombre avant la comparaison:
'1' < 2 // true
'3' > 2 // true
true > '2' // false (true implicitly converted to number, 1 < 2)
Lorsque la chaîne est non numérique, la conversion numérique renvoie NaN
(pas un nombre). La comparaison avec NaN
renvoie toujours false
:
1 < 'abc' // false
1 > 'abc' // false
Mais soyez prudent lorsque vous comparez une valeur numérique avec des chaînes null
, undefined
ou vides:
1 > '' // true
1 < '' // false
1 > null // true
1 < null // false
1 > undefined // false
1 < undefined // false
Lorsqu'un opérande est un objet et que l'autre est un nombre, l'objet est converti en nombre avant la comparaison. Ainsi, null
est un cas particulier car Number(null);//0
new Date(2015)< 1479480185280 // true
null > -1 //true
({toString:function(){return 123}}) > 122 //true
Inégalité
L'opérateur !=
Est l'inverse de l'opérateur ==
.
Renvoie true
si les opérandes ne sont pas égaux.
Le moteur JavaScript essaiera de convertir les deux opérandes en types correspondants s'ils ne sont pas du même type. Note: si les deux opérandes ont des références internes différentes en mémoire, alors false
sera renvoyé.
Échantillon:
1 != '1' // false
1 != 2 // true
Dans l'exemple ci - dessus, 1 != '1'
est false
parce que, un type de numéro primitif est comparé à un char
valeur. Par conséquent, le moteur Javascript ne se soucie pas du type de données de la valeur RHS.
Opérateur !==
est l'inverse de l'opérateur ===
. Renvoie true si les opérandes ne sont pas égaux ou si leurs types ne correspondent pas.
Exemple:
1 !== '1' // true
1 !== 2 // true
1 !== 1 // false
Opérateurs logiques avec des valeurs non booléennes (coercition booléenne)
Logical OR ( ||
), lisant de gauche à droite, évaluera la première valeur de vérité . Si aucune valeur de vérité n'est trouvée, la dernière valeur est renvoyée.
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'
Logical AND ( &&
), en lisant de gauche à droite, évaluera à la première valeur de falsy . Si aucune valeur de falsey n'est trouvée, la dernière valeur est renvoyée.
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
Cette astuce peut être utilisée, par exemple, pour définir une valeur par défaut sur un argument de fonction (antérieur à 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
Gardez juste à l'esprit que pour les arguments, 0
et (dans une moindre mesure) la chaîne vide sont aussi souvent des valeurs valides qui devraient pouvoir être explicitement passées et remplacer une valeur par défaut, ce qui, avec ce modèle, ne le sera pas (parce qu'elles sont fausses ).
Null et indéfini
Les différences entre null
et undefined
égalité abstraite de part de partage null
et undefined
==
mais pas d'égalité stricte ===
,
null == undefined // true
null === undefined // false
Ils représentent des choses légèrement différentes:
-
undefined
représente l' absence d'une valeur , par exemple avant la création d'une propriété identifiant / objet ou dans la période entre la création du paramètre identifiant / fonction et son premier ensemble, le cas échéant. -
null
représente l' absence intentionnelle d'une valeur pour un identifiant ou une propriété déjà créé.
Ce sont différents types de syntaxe:
-
undefined
est une propriété de l'objet global , généralement immuable dans la portée globale. Cela signifie que partout où vous pouvez définir un identifiant autre que dans l'espace de nommage global pourrait cacherundefined
de ce champ (bien que les choses peuvent encore êtreundefined
) -
null
est un littéral de mot , donc sa signification ne peut jamais être modifiée et tenter de le faire va générer une erreur .
Les similitudes entre null
et undefined
null
et undefined
sont tous deux falsifiés.
if (null) console.log("won't be logged");
if (undefined) console.log("won't be logged");
Ni null
ni undefined
égal à false
(voir cette question ).
false == undefined // false
false == null // false
false === undefined // false
false === null // false
Utiliser undefined
- Si la portée actuelle ne peut pas être approuvée, utilisez quelque chose qui est considéré comme indéfini , par exemple
void 0;
. - Si
undefined
est ombré par une autre valeur, il est tout aussi mauvais que ShadowArray
ouNumber
. - Évitez de définir quelque chose comme
undefined
. Si vous souhaitez supprimer une barre de propriété d'un objetfoo
,delete foo.bar;
au lieu. - L'identifiant de test d'existence
foo
contreundefined
pourraittypeof foo
une erreur de référence , mais utilisertypeof foo
contre"undefined"
.
Propriété NaN de l'objet global
NaN
(" N ot a N umber") est une valeur spéciale définie par la norme IEEE pour l'arithmétique en virgule flottante , qui est utilisée lorsqu'une valeur non numérique est fournie, mais qu'un nombre est attendu ( 1 * "two"
), ou lorsqu'un calcul n'a pas de résultat de number
valide ( Math.sqrt(-1)
).
Toute égalité ou comparaison relationnelle avec NaN
renvoie false
, même en la comparant à elle-même. Parce que, NaN
est supposé dénoter le résultat d’un calcul absurde, et en tant que tel, il n’est pas égal au résultat d’autres calculs absurdes.
(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
Les comparaisons non égales renvoient toujours true
:
NaN !== 0; // true
NaN !== NaN; // true
Vérifier si une valeur est NaN
Vous pouvez tester une valeur ou une expression pour NaN
en utilisant la fonction 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
Vous pouvez vérifier si une valeur est NaN
en la comparant à elle-même:
value !== value; // true for NaN, false for any other value
Vous pouvez utiliser le polyfill suivant pour Number.isNaN()
:
Number.isNaN = Number.isNaN || function(value) {
return value !== value;
}
En revanche, la fonction globale isNaN()
renvoie true
non seulement pour NaN
, mais aussi pour toute valeur ou expression qui ne peut pas être forcée dans un nombre:
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 définit un algorithme de «similitude» appelé SameValue
qui, depuis ECMAScript 6, peut être Object.is
avec Object.is
. Contrairement à la comparaison ==
et ===
, l'utilisation d' Object.is()
traitera NaN
comme identique à lui-même (et -0
comme pas identique à +0
):
Object.is(NaN, NaN) // true
Object.is(+0, 0) // false
NaN === NaN // false
+0 === 0 // true
Vous pouvez utiliser le polyfill suivant pour Object.is()
(à partir de 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;
}
};
}
Points à noter
NaN lui-même est un nombre, ce qui signifie qu'il n'est pas égal à la chaîne "NaN", et le plus important (mais peut-être de manière non intuitive):
typeof(NaN) === "number"; //true
Court-circuit dans les opérateurs booléens
L'opérateur-opérateur ( &&
) et l'opérateur-opérateur ( ||
) utilisent un court-circuit pour empêcher tout travail inutile si le résultat de l'opération ne change pas avec le travail supplémentaire.
Dans x && y
, y
ne sera pas évalué si x
évalué comme false
, car l'expression entière est garantie être false
.
En x || y
, y
ne sera pas évalué si x
évalué à true
, car il est garanti que toute l'expression est true
.
Exemple avec des fonctions
Prenez les deux fonctions suivantes:
function T() { // True
console.log("T");
return true;
}
function F() { // False
console.log("F");
return false;
}
Exemple 1
T() && F(); // false
Sortie:
'T'
'F'
Exemple 2
F() && T(); // false
Sortie:
'F'
Exemple 3
T() || F(); // true
Sortie:
'T'
Exemple 4
F() || T(); // true
Sortie:
'F'
'T'
Court-circuit pour éviter les erreurs
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
Ligne A: si vous inversez la commande, la première instruction conditionnelle empêchera l'erreur sur la seconde en ne l'exécutant pas si elle génère l'erreur
if(obj !== undefined && obj.property){}; // no error thrown
Mais ne devrait être utilisé que si vous attendez undefined
if(typeof obj === "object" && obj.property){}; // safe option but slower
Court-circuit pour fournir une valeur par défaut
Le ||
L'opérateur peut être utilisé pour sélectionner une valeur "Vérité" ou la valeur par défaut.
Par exemple, cela peut être utilisé pour garantir qu'une valeur nullable est convertie en une valeur non nullable:
var nullableObj = null;
var obj = nullableObj || {}; // this selects {}
var nullableObj2 = {x: 5};
var obj2 = nullableObj2 || {} // this selects {x: 5}
Ou pour retourner la première valeur véridique
var truthyValue = {x: 10};
return truthyValue || {}; // will return {x: 10}
La même chose peut être utilisée pour reculer plusieurs fois:
envVariable || configValue || defaultConstValue // select the first "truthy" of these
Court-circuit pour appeler une fonction optionnelle
L'opérateur &&
peut être utilisé pour évaluer un rappel, uniquement s'il est transmis:
function myMethod(cb) {
// This can be simplified
if (cb) {
cb();
}
// To this
cb && cb();
}
Bien sûr, le test ci-dessus ne valide pas que cb
est en fait une function
et pas seulement un Object
/ Array
/ String
/ Number
.
Egalité abstraite / inégalité et conversion de type
Le problème
Les opérateurs d'égalité abstraite et d'inégalité ( ==
et !=
) Convertissent leurs opérandes si les types d'opérandes ne correspondent pas. Ce type de coercition est une source commune de confusion sur les résultats de ces opérateurs, en particulier, ces opérateurs ne sont pas toujours transitifs comme on pourrait s’y attendre.
"" == 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
Les résultats commencent à avoir un sens si vous considérez comment JavaScript convertit les chaînes vides en nombres.
Number(""); // 0
Number("0"); // 0
Number(false); // 0
La solution
Dans la déclaration false B
, les deux opérandes sont des chaînes ( ""
et "0"
), il n'y aura donc pas de conversion de type et puisque ""
et "0"
n'ont pas la même valeur, "" == "0"
est false
comme prévu.
Une façon d'éliminer les comportements inattendus est de toujours comparer les opérandes du même type. Par exemple, si vous souhaitez que les résultats de la comparaison numérique utilisent une conversion explicite:
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
Ou, si vous voulez une comparaison de chaînes:
var test = (a,b) => String(a) == String(b);
test("", 0); // false;
test("0", 0); // true
test("", "0"); // false;
Note : Le Number("0")
et le new Number("0")
ne sont pas la même chose! Alors que le premier effectue une conversion de type, le second crée un nouvel objet. Les objets sont comparés par référence et non par valeur, ce qui explique les résultats ci-dessous.
Number("0") == Number("0"); // true;
new Number("0") == new Number("0"); // false
Enfin, vous avez la possibilité d'utiliser des opérateurs d'égalité et d'inégalité stricts qui n'effectueront aucune conversion de type implicite.
"" === 0; // false
0 === "0"; // false
"" === "0"; // false
Vous trouverez d'autres références à ce sujet ici:
Quel est l'opérateur égal (== vs ===) à utiliser dans les comparaisons JavaScript? .
Tableau vide
/* ToNumber(ToPrimitive([])) == ToNumber(false) */
[] == false; // true
Lorsque [].toString()
est exécuté, il appelle [].join()
s'il existe, ou Object.prototype.toString()
sinon. Cette comparaison renvoie true
car [].join()
renvoie ''
qui, forcé dans 0
, est égal à false ToNumber .
Attention cependant, tous les objets sont véridiques et Array
est une instance de Object
:
// Internally this is evaluated as ToBoolean([]) === true ? 'truthy' : 'falsy'
[] ? 'truthy' : 'falsy'; // 'truthy'
Opérations de comparaison d'égalité
JavaScript a quatre opérations de comparaison d'égalité différentes.
SameValue
Il renvoie true
si les deux opérandes appartiennent au même type et ont la même valeur.
Note: la valeur d'un objet est une référence.
Vous pouvez utiliser cet algorithme de comparaison via Object.is
(ECMAScript 6).
Exemples:
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
Cet algorithme a les propriétés d'une relation d'équivalence :
- Réflexivité :
Object.is(x, x)
esttrue
, pour toute valeurx
- Symétrie :
Object.is(x, y)
esttrue
si et seulement siObject.is(y, x)
esttrue
pour toutes les valeursx
ety
. - Transitivité : si
Object.is(x, y)
etObject.is(y, z)
sonttrue
,Object.is(x, z)
est égalementtrue
pour toutes les valeursx
,y
etz
.
SameValueZero
Il se comporte comme SameValue, mais considère que +0
et -0
sont égaux.
Vous pouvez utiliser cet algorithme de comparaison via Array.prototype.includes
(ECMAScript 7).
Exemples:
[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
Cet algorithme a toujours les propriétés d'une relation d'équivalence :
- Réflexivité :
[x].includes(x)
esttrue
, pour toute valeurx
- Symétrie :
[x].includes(y)
esttrue
si et seulement si[y].includes(x)
esttrue
pour toutes les valeursx
ety
. - Transitivité : Si
[x].includes(y)
et[y].includes(z)
sonttrue
, alors[x].includes(z)
est égalementtrue
pour toutes les valeursx
,y
etz
.
Comparaison stricte de l'égalité
Il se comporte comme SameValue, mais
- Considère que
+0
et-0
sont égaux. - Considère
NaN
différent de toute valeur, y compris lui-même
Vous pouvez utiliser cet algorithme de comparaison via l'opérateur ===
(ECMAScript 3).
Il y a aussi l'opérateur !==
(ECMAScript 3), qui annule le résultat de ===
.
Exemples:
1 === 1; // true
+0 === -0; // true
NaN === NaN; // false
true === "true"; // false
false === 0; // false
1 === "1"; // false
null === undefined; // false
[] === []; // false
Cet algorithme a les propriétés suivantes:
- Symétrie :
x === y
esttrue
si, et seulement si, y === xis
vrai, for any values
xand
y`. - Transitivité : Si
x === y
ety === z
sonttrue
, alorsx === z
est égalementtrue
pour toutes les valeursx
,y
etz
.
Mais n'est pas une relation d'équivalence car
-
NaN
n'est pas réflexif :NaN !== NaN
Comparaison d'égalité abstraite
Si les deux opérandes appartiennent au même type, il se comporte comme la comparaison stricte d'égalité.
Sinon, il les contraint comme suit:
-
undefined
etnull
sont considérés comme égaux - Lorsque vous comparez un nombre avec une chaîne, la chaîne est forcée à un nombre
- En comparant un booléen avec autre chose, le booléen est forcé à un nombre
- Lors de la comparaison d'un objet avec un nombre, une chaîne ou un symbole, l'objet est contraint à une primitive
S'il y avait coercition, les valeurs coercitives sont comparées récursivement. Sinon, l'algorithme retourne false
.
Vous pouvez utiliser cet algorithme de comparaison via l'opérateur ==
(ECMAScript 1).
Il y a aussi l'opérateur !=
(ECMAScript 1), qui annule le résultat de ==
.
Exemples:
1 == 1; // true
+0 == -0; // true
NaN == NaN; // false
true == "true"; // false
false == 0; // true
1 == "1"; // true
null == undefined; // true
[] == []; // false
Cet algorithme a la propriété suivante:
- Symétrie :
x == y
esttrue
si et seulement siy == x
esttrue
pour toutes les valeursx
ety
.
Mais n'est pas une relation d'équivalence car
-
NaN
n'est pas réflexif :NaN != NaN
- La transitivité ne tient pas, par exemple
0 == ''
et0 == '0'
, mais'' != '0'
Regroupement de plusieurs instructions logiques
Vous pouvez regrouper plusieurs instructions logiques booléennes entre parenthèses afin de créer une évaluation logique plus complexe, particulièrement utile dans les instructions if.
if ((age >= 18 && height >= 5.11) || (status === 'royalty' && hasInvitation)) {
console.log('You can enter our club');
}
Nous pourrions également déplacer la logique groupée vers des variables pour raccourcir et décrire l’instruction:
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');
Notez que dans cet exemple particulier (et beaucoup d'autres), le regroupement des instructions avec des parenthèses fonctionne de la même manière que si nous les supprimions, suivez simplement une évaluation de logique linéaire et vous vous retrouverez avec le même résultat. Je préfère utiliser les parenthèses, car cela me permet de comprendre plus clairement ce que je voulais et de prévenir les erreurs de logique.
Conversions de type automatique
Attention, les nombres peuvent être convertis accidentellement en chaînes ou en NaN (pas un nombre).
JavaScript est tapé librement. Une variable peut contenir différents types de données et une variable peut modifier son type de données:
var x = "Hello"; // typeof x is a string
x = 5; // changes typeof x to a number
Lors d'opérations mathématiques, JavaScript peut convertir des nombres en chaînes:
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
Soustraire une chaîne à une chaîne ne génère pas d'erreur mais renvoie NaN (pas un nombre):
"Hello" - "Dolly" // returns NaN
Liste des opérateurs de comparaison
Opérateur | Comparaison | Exemple |
---|---|---|
== | Égal | i == 0 |
=== | Valeur et type égaux | i === "5" |
!= | Inégal | i != 5 |
!== | Valeur ou type non égal | i !== 5 |
> | Plus grand que | i > 5 |
< | Moins que | i < 5 |
>= | Meilleur que ou égal | i >= 5 |
<= | Inférieur ou égal | i <= 5 |
Champs de bits pour optimiser la comparaison de données multi-états
Un champ de bits est une variable qui contient différents états booléens en tant que bits individuels. Un peu sur représenterait vrai, et off serait faux. Dans le passé, les champs de bits étaient couramment utilisés car ils économisaient de la mémoire et réduisaient la charge de traitement. Bien que le besoin d'utiliser des champs de bits ne soit plus si important, ils offrent certains avantages qui peuvent simplifier de nombreuses tâches de traitement.
Par exemple, saisie utilisateur. Lors de la saisie des touches de direction du clavier vers le haut, le bas, la gauche et la droite, vous pouvez encoder les différentes clés en une seule variable avec chaque direction assignée à un bit.
Exemple de lecture du clavier 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];
}
}
}
Exemple de lecture en tableau
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";
}
}
Pour activer un bit, utilisez bitwise ou |
et la valeur correspondant au bit. Donc, si vous souhaitez définir le 2ème bit, bitField |= 0b10
l’ bitField |= 0b10
. Si vous souhaitez désactiver un peu, utilisez bitwise et &
avec une valeur qui a tous le bit requis. Utiliser 4 bits et éteindre le bit bit bitfield &= 0b1101;
Vous pouvez dire que l'exemple ci-dessus semble beaucoup plus complexe que d'attribuer les différents états clés à un tableau. Oui, c'est un peu plus complexe à mettre en place mais l'avantage vient quand on interroge l'état.
Si vous voulez tester si toutes les clés sont en place.
// 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])){
Vous pouvez définir des constantes pour faciliter les choses
// 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
Vous pouvez ensuite tester rapidement plusieurs états de clavier
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
La saisie au clavier n'est qu'un exemple. Les champs de bits sont utiles lorsque vous devez combiner différents états. Javascript peut utiliser jusqu'à 32 bits pour un champ de bits. Leur utilisation peut offrir des augmentations de performances significatives. Ils valent la peine d'être familiers.