Buscar..
Observaciones
Cuando se utiliza la coerción booleana, los siguientes valores se consideran "falsos" :
-
false -
0 -
""(cadena vacía) -
null -
undefined -
NaN(no es un número, por ejemplo,0/0) -
document.all¹ (contexto del navegador)
Todo lo demás se considera "veraz" .
Violation violación voluntaria de la especificación ECMAScript
Operadores logicos con booleanos
var x = true,
y = false;
Y
Este operador devolverá verdadero si ambas expresiones se evalúan como verdaderas. Este operador booleano empleará un cortocircuito y no evaluará y si x evalúa como false .
x && y;
Esto devolverá falso, porque y es falso.
O
Este operador devolverá verdadero si una de las dos expresiones se evalúa como verdadera. Este operador booleano empleará cortocircuito e y no se evaluará si x evalúa como true .
x || y;
Esto devolverá verdadero, porque x es verdadero.
NO
Este operador devolverá false si la expresión de la derecha se evalúa como true, y devolverá true si la expresión de la derecha se evalúa como false.
!x;
Esto devolverá falso, porque x es verdadero.
Igualdad abstracta (==)
Los operandos del operador de igualdad abstracta se comparan después de convertirse a un tipo común. Cómo se realiza esta conversión se basa en la especificación del operador:
Especificación para el operador == :
7.2.13 Comparación de igualdad abstracta
La comparaciónx == y, dondexeyson valores, producetrueofalse. Tal comparación se realiza de la siguiente manera:
- Si el
Type(x)es el mismo que elType(y), entonces:
- a. Devuelve el resultado de realizar una comparación de igualdad estricta
x === y.
- Si
xesnulleyundefinedestáundefined, devuelvatrue.- Si
xundefinedestáundefinedyyesnull, devuelvatrue.- Si el
Type(x)esNumbery elType(y)esString, devuelva el resultado de la comparaciónx == ToNumber(y).- Si el
Type(x)esStringy elType(y)esNumber, devuelva el resultado de la comparación aToNumber(x) == y.- Si el
Type(x)esBoolean, devuelva el resultado de la comparación aToNumber(x) == y.- Si el
Type(y)esBoolean, devuelva el resultado de lacomparison x == ToNumber(y).- Si el
Type(x)esString,NumberoSymboly elType(y)esObject, devuelva el resultado de la comparaciónx == ToPrimitive(y).- Si el
Type(x)es Objeto y elType(y)esString,NumberoSymbol, devuelva el resultado de la comparaciónToPrimitive(x) == y.- Devuelve
false
Ejemplos:
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
Operadores relacionales (<, <=,>,> =)
Cuando ambos operandos son numéricos, se comparan normalmente:
1 < 2 // true
2 <= 2 // true
3 >= 5 // false
true < false // false (implicitly converted to numbers, 1 > 0)
Cuando ambos operandos son cadenas, se comparan lexicográficamente (de acuerdo con el orden alfabético):
'a' < 'b' // true
'1' < '2' // true
'100' > '12' // false ('100' is less than '12' lexicographically!)
Cuando un operando es una cadena y el otro es un número, la cadena se convierte en un número antes de la comparación:
'1' < 2 // true
'3' > 2 // true
true > '2' // false (true implicitly converted to number, 1 < 2)
Cuando la cadena no es numérica, la conversión numérica devuelve NaN (no es un número). Comparando con NaN siempre devuelve false :
1 < 'abc' // false
1 > 'abc' // false
Pero tenga cuidado al comparar un valor numérico con cadenas null , undefined o vacías:
1 > '' // true
1 < '' // false
1 > null // true
1 < null // false
1 > undefined // false
1 < undefined // false
Cuando un operando es un objeto y el otro es un número, el objeto se convierte en un número antes de la comparación. Por lo tanto, null es un caso particular porque Number(null);//0
new Date(2015)< 1479480185280 // true
null > -1 //true
({toString:function(){return 123}}) > 122 //true
Desigualdad
Operator != Es el inverso del operador == .
Devolverá true si los operandos no son iguales.
El motor de javascript intentará convertir ambos operandos a tipos coincidentes si no son del mismo tipo. Nota: si los dos operandos tienen diferentes referencias internas en la memoria, entonces se devolverá false .
Muestra:
1 != '1' // false
1 != 2 // true
En el ejemplo anterior, 1 != '1' es false porque se está comparando un tipo de número primitivo con un valor char . Por lo tanto, el motor de Javascript no se preocupa por el tipo de datos del valor RHS.
Operador !== es el inverso del operador === . Devolverá verdadero si los operandos no son iguales o si sus tipos no coinciden.
Ejemplo:
1 !== '1' // true
1 !== 2 // true
1 !== 1 // false
Operadores lógicos con valores no booleanos (coerción booleana)
El OR lógico ( || ), leyendo de izquierda a derecha, evaluará el primer valor verdadero . Si no se encuentra un valor verdadero , se devuelve el último valor.
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'
AND lógico ( && ), leyendo de izquierda a derecha, evaluará el primer valor falso . Si no se encuentra ningún valor falsey , se devuelve el último valor.
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
Este truco se puede usar, por ejemplo, para establecer un valor predeterminado para un argumento de función (antes de 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
Solo tenga en cuenta que para los argumentos, 0 y (en menor medida) la cadena vacía a menudo también son valores válidos que deberían poder pasar explícitamente y anular un valor predeterminado, que, con este patrón, no lo harán (porque son falsos ).
Nulo e indefinido
Las diferencias entre null e undefined
null e undefined comparten igualdad abstracta == pero no estricta igualdad === ,
null == undefined // true
null === undefined // false
Representan cosas ligeramente diferentes:
-
undefinedrepresenta la ausencia de un valor , como antes de que se haya creado un identificador / propiedad Objeto o en el período entre el identificador / parámetro de función de creación y su primer conjunto, si lo hubiera. -
nullrepresenta la ausencia intencional de un valor para un identificador o propiedad que ya se ha creado.
Son diferentes tipos de sintaxis:
-
undefinedes una propiedad del Objeto global , generalmente inmutable en el ámbito global. Esto significa que en cualquier lugar donde pueda definir un identificador que no sea el espacio de nombres global podría esconderseundefinedde ese alcance (aunque las cosas todavía pueden estarundefined) -
nulles una palabra literal , por lo que su significado nunca puede cambiarse e intentar hacerlo generará un error .
Las similitudes entre null e undefined
null e undefined son falsos.
if (null) console.log("won't be logged");
if (undefined) console.log("won't be logged");
Ni null ni undefined igual false (vea esta pregunta ).
false == undefined // false
false == null // false
false === undefined // false
false === null // false
Usando undefined
- Si no se puede confiar en el alcance actual, use algo que se evalúe como indefinido , por ejemplo,
void 0;. - Si
undefinedestá sombreado por otro valor, es tan malo como sombrearArrayoNumber. - Evita establecer algo como
undefined. Si desea eliminar una barra de propiedades de un objetofoo,delete foo.bar;en lugar. - El identificador de prueba de existencia
foocontraundefinedpodría generar un error de referencia , en su lugar usetypeof foocontra"undefined".
Propiedad NaN del objeto global
NaN (" N ot a N umber") es un valor especial definido por el Estándar IEEE para la aritmética de punto flotante , que se usa cuando se proporciona un valor no numérico pero se espera un número ( 1 * "two" ), o cuando un cálculo no tiene un resultado de number válido ( Math.sqrt(-1) ).
Cualquier comparación de igualdad o relacional con NaN devuelve false , incluso comparándolo con sí mismo. Porque, se supone que NaN denota el resultado de un cálculo sin sentido, y como tal, no es igual al resultado de cualquier otro cálculo sin sentido.
(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
Las comparaciones no iguales siempre devolverán true :
NaN !== 0; // true
NaN !== NaN; // true
Comprobando si un valor es NaN
Puede probar un valor o expresión para NaN usando la función 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
Puede verificar si un valor es NaN comparándolo consigo mismo:
value !== value; // true for NaN, false for any other value
Puedes usar el siguiente polyfill para Number.isNaN() :
Number.isNaN = Number.isNaN || function(value) {
return value !== value;
}
Por el contrario, la función global isNaN() devuelve true no solo para NaN , sino también para cualquier valor o expresión que no se pueda forzar a un número:
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 define un algoritmo de "similitud" llamado SameValue que, desde ECMAScript 6, se puede invocar con Object.is . A diferencia de la comparación == y === , usar Object.is() tratará a NaN como idéntico a sí mismo (y -0 como no idéntico a +0 ):
Object.is(NaN, NaN) // true
Object.is(+0, 0) // false
NaN === NaN // false
+0 === 0 // true
Puede usar el siguiente polyfill para Object.is() (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;
}
};
}
Puntos a tener en cuenta
NaN en sí es un número, lo que significa que no es igual a la cadena "NaN", y lo más importante (aunque quizás de manera no intuitiva):
typeof(NaN) === "number"; //true
Cortocircuito en operadores booleanos.
El operador-e ( && ) y el operador-o ( || ) emplean cortocircuitos para evitar trabajos innecesarios si el resultado de la operación no cambia con el trabajo adicional.
En x && y , y no se evaluará si x evalúa como false , porque se garantiza que toda la expresión es false .
En x || y , y no se evaluará si x evalúa como true , porque se garantiza que toda la expresión es true .
Ejemplo con funciones
Tome las siguientes dos funciones:
function T() { // True
console.log("T");
return true;
}
function F() { // False
console.log("F");
return false;
}
Ejemplo 1
T() && F(); // false
Salida:
'T'
'F'
Ejemplo 2
F() && T(); // false
Salida:
'F'
Ejemplo 3
T() || F(); // true
Salida:
'T'
Ejemplo 4
F() || T(); // true
Salida:
'F'
'T'
Cortocircuito para evitar errores.
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
Línea A: si invierte el orden, la primera declaración condicional evitará el error en el segundo al no ejecutarlo si arrojaría el error
if(obj !== undefined && obj.property){}; // no error thrown
Pero solo se debe usar si esperas undefined
if(typeof obj === "object" && obj.property){}; // safe option but slower
Cortocircuito para proporcionar un valor predeterminado
El || El operador se puede usar para seleccionar un valor "verdadero" o el valor predeterminado.
Por ejemplo, esto se puede usar para asegurar que un valor anulable se convierta en un valor no anulable:
var nullableObj = null;
var obj = nullableObj || {}; // this selects {}
var nullableObj2 = {x: 5};
var obj2 = nullableObj2 || {} // this selects {x: 5}
O devolver el primer valor de verdad.
var truthyValue = {x: 10};
return truthyValue || {}; // will return {x: 10}
Lo mismo se puede usar para retroceder varias veces:
envVariable || configValue || defaultConstValue // select the first "truthy" of these
Cortocircuito para llamar a una función opcional
El operador && se puede usar para evaluar una devolución de llamada, solo si se pasa:
function myMethod(cb) {
// This can be simplified
if (cb) {
cb();
}
// To this
cb && cb();
}
Por supuesto, la prueba anterior no valida que cb sea en realidad una function y no solo un Object / Array / String / Number .
Resumen igualdad / desigualdad y conversión de tipos
El problema
Los operadores abstractos de igualdad y desigualdad ( == y != ) Convierten sus operandos si los tipos de operandos no coinciden. Este tipo de coerción es una fuente común de confusión sobre los resultados de estos operadores, en particular, estos operadores no siempre son transitivos como se podría esperar.
"" == 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
Los resultados comienzan a tener sentido si considera cómo JavaScript convierte las cadenas vacías en números.
Number(""); // 0
Number("0"); // 0
Number(false); // 0
La solución
En la declaración false B , ambos operandos son cadenas ( "" y "0" ), por lo tanto no habrá conversión de tipos y como "" y "0" no tienen el mismo valor, "" == "0" es false como se esperaba.
Una forma de eliminar el comportamiento inesperado aquí es asegurarse de que siempre compare operandos del mismo tipo. Por ejemplo, si desea que los resultados de la comparación numérica use conversión explícita:
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
O, si quieres comparación de cadenas:
var test = (a,b) => String(a) == String(b);
test("", 0); // false;
test("0", 0); // true
test("", "0"); // false;
Nota al margen : ¡El Number("0") y el new Number("0") no son lo mismo! Mientras que el primero realiza una conversión de tipo, el segundo creará un nuevo objeto. Los objetos se comparan por referencia y no por valor, lo que explica los resultados a continuación.
Number("0") == Number("0"); // true;
new Number("0") == new Number("0"); // false
Finalmente, tiene la opción de utilizar operadores de igualdad y desigualdad estrictos que no realizarán conversiones de tipo implícitas.
"" === 0; // false
0 === "0"; // false
"" === "0"; // false
Más referencia a este tema se puede encontrar aquí:
¿Qué operador igual (== vs ===) se debe usar en las comparaciones de JavaScript? .
Matriz vacía
/* ToNumber(ToPrimitive([])) == ToNumber(false) */
[] == false; // true
Cuando se ejecuta [].toString() , llama a [].join() si existe, o Object.prototype.toString() contrario. Esta comparación devuelve true porque [].join() devuelve '' que, forzado en 0 , es igual a fallar ToNumber .
Sin embargo, tenga cuidado, todos los objetos son sinceros y Array es una instancia de Object :
// Internally this is evaluated as ToBoolean([]) === true ? 'truthy' : 'falsy'
[] ? 'truthy' : 'falsy'; // 'truthy'
Operaciones de comparación de igualdad
JavaScript tiene cuatro operaciones de comparación de igualdad diferentes.
SameValue
Devuelve true si ambos operandos pertenecen al mismo Tipo y tienen el mismo valor.
Nota: el valor de un objeto es una referencia.
Puede utilizar este algoritmo de comparación a través de Object.is (ECMAScript 6).
Ejemplos:
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
Este algoritmo tiene las propiedades de una relación de equivalencia :
- Reflexividad :
Object.is(x, x)estrue, para cualquier valorx - Simetría :
Object.is(x, y)estruesi, y solo si,Object.is(y, x)estrue, para cualquier valor dexey. - Transitividad : si
Object.is(x, y)yObject.is(y, z)sontrue,Object.is(x, z)también estrue, para cualquier valor dex,yyz.
SameValueZero
Se comporta como SameValue, pero considera que +0 y -0 son iguales.
Puede usar este algoritmo de comparación a través de Array.prototype.includes (ECMAScript 7).
Ejemplos:
[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
Este algoritmo todavía tiene las propiedades de una relación de equivalencia :
- Reflexividad :
[x].includes(x)estrue, para cualquier valorx - Simetría :
[x].includes(y)estruesi, y solo si,[y].includes(x)estrue, para cualquier valor dexey. - Transitividad : si
[x].includes(y)y[y].includes(z)sontrue, entonces[x].includes(z)también estrue, para cualquier valor dex,y,yz.
Comparación de igualdad estricta
Se comporta como SameValue, pero
- Considera que
+0y-0son iguales. - Considera
NaNdiferente a cualquier valor, incluyéndose a sí mismo.
Puede utilizar este algoritmo de comparación a través del operador === (ECMAScript 3).
También está el operador !== (ECMAScript 3), que niega el resultado de === .
Ejemplos:
1 === 1; // true
+0 === -0; // true
NaN === NaN; // false
true === "true"; // false
false === 0; // false
1 === "1"; // false
null === undefined; // false
[] === []; // false
Este algoritmo tiene las siguientes propiedades:
- Simetría :
x === yestruesi, y solo si, y === xisverdadero, for any valuesxandy`. - Transitividad : si
x === yyy === zsontrue, entoncesx === ztambién estrue, para cualquier valorx,y,yz.
Pero no es una relación de equivalencia porque
-
NaNno es reflexivo :NaN !== NaN
Comparación de igualdad abstracta
Si ambos operandos pertenecen al mismo tipo, se comporta como la comparación de igualdad estricta.
De lo contrario, los obliga a lo siguiente:
-
undefinedynullse consideran iguales - Cuando se compara un número con una cadena, la cadena se convierte en un número
- Cuando se compara un booleano con otra cosa, el booleano se fuerza a un número
- Cuando se compara un objeto con un número, una cadena o un símbolo, el objeto es obligado a un primitivo
Si hubo una coerción, los valores coercitivos se comparan recursivamente. De lo contrario, el algoritmo devuelve false .
Puede utilizar este algoritmo de comparación a través del operador == (ECMAScript 1).
También está el operador != (ECMAScript 1), que niega el resultado de == .
Ejemplos:
1 == 1; // true
+0 == -0; // true
NaN == NaN; // false
true == "true"; // false
false == 0; // true
1 == "1"; // true
null == undefined; // true
[] == []; // false
Este algoritmo tiene la siguiente propiedad:
- Simetría :
x == yestruesi, y solo si,y == xestrue, para cualquier valorxey.
Pero no es una relación de equivalencia porque
-
NaNno es reflexivo :NaN != NaN - La transitividad no se mantiene, por ejemplo,
0 == ''y0 == '0', pero'' != '0'
Agrupando múltiples declaraciones lógicas
Puede agrupar varias declaraciones lógicas booleanas entre paréntesis para crear una evaluación lógica más compleja, especialmente útil en declaraciones if.
if ((age >= 18 && height >= 5.11) || (status === 'royalty' && hasInvitation)) {
console.log('You can enter our club');
}
También podríamos mover la lógica agrupada a variables para hacer la declaración un poco más corta y descriptiva:
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');
Tenga en cuenta que en este ejemplo particular (y en muchos otros), agrupar las declaraciones con paréntesis funciona igual que si las elimináramos, simplemente siga una evaluación de lógica lineal y se encontrará con el mismo resultado. Prefiero usar paréntesis ya que me permite entender más claramente lo que pretendía y podría evitar errores lógicos.
Conversiones automáticas de tipos
Tenga en cuenta que los números pueden convertirse accidentalmente a cadenas o NaN (no es un número).
JavaScript está escrito a la ligera. Una variable puede contener diferentes tipos de datos, y una variable puede cambiar su tipo de datos:
var x = "Hello"; // typeof x is a string
x = 5; // changes typeof x to a number
Al realizar operaciones matemáticas, JavaScript puede convertir números en cadenas:
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
Restar una cadena de una cadena, no genera un error pero devuelve NaN (no es un número):
"Hello" - "Dolly" // returns NaN
Lista de operadores de comparación
| Operador | Comparación | Ejemplo |
|---|---|---|
== | Igual | i == 0 |
=== | Igual valor y tipo | i === "5" |
!= | No es igual | i != 5 |
!== | No igual valor o tipo | i !== 5 |
> | Mas grande que | i > 5 |
< | Menos que | i < 5 |
>= | Mayor que o igual | i >= 5 |
<= | Menor o igual | i <= 5 |
Campos de bits para optimizar la comparación de datos de múltiples estados
Un campo de bits es una variable que contiene varios estados booleanos como bits individuales. Un poco encendido representaría verdadero, y apagado sería falso. En el pasado, los campos de bits se usaban de forma rutinaria ya que guardaban memoria y reducían la carga de procesamiento. Aunque la necesidad de utilizar el campo de bits ya no es tan importante, sí ofrecen algunos beneficios que pueden simplificar muchas tareas de procesamiento.
Por ejemplo, la entrada del usuario. Al obtener información de las teclas de dirección de un teclado arriba, abajo, izquierda, derecha, puede codificar las distintas teclas en una sola variable con cada dirección asignada un bit.
Ejemplo de teclado de lectura a través de campo de bits
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];
}
}
}
Ejemplo de lectura como una matriz
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";
}
}
Para activar un bit use bitwise o | y el valor correspondiente al bit. Por lo tanto, si desea establecer el segundo bit, bitField |= 0b10 activará. Si desea desactivar un bit, use bitwise y & con un valor que tenga todo por el bit requerido activado. Utilizando 4 bits y desactivando el segundo bit del bitfield &= 0b1101; de bitfield &= 0b1101;
Puede decir que el ejemplo anterior parece mucho más complejo que asignar los diversos estados clave a una matriz. Sí. Es un poco más complejo de establecer, pero la ventaja viene al interrogar al estado.
Si quieres probar si todas las teclas están arriba.
// 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])){
Puedes configurar algunas constantes para facilitar las cosas.
// 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
A continuación, puede probar rápidamente varios estados de teclado diferentes
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 entrada del teclado es solo un ejemplo. Los campos de bits son útiles cuando tiene varios estados en los que se debe actuar en combinación. Javascript puede usar hasta 32 bits para un campo de bits. Su uso puede ofrecer aumentos significativos de rendimiento. Vale la pena estar familiarizados con ellos.