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ón x == y , donde x e y son valores, produce true o false . Tal comparación se realiza de la siguiente manera:

  1. Si el Type(x) es el mismo que el Type(y) , entonces:
  • a. Devuelve el resultado de realizar una comparación de igualdad estricta x === y .
  1. Si x es null e y undefined está undefined , devuelva true .
  2. Si x undefined está undefined y y es null , devuelva true .
  3. Si el Type(x) es Number y el Type(y) es String , devuelva el resultado de la comparación x == ToNumber(y) .
  4. Si el Type(x) es String y el Type(y) es Number , devuelva el resultado de la comparación a ToNumber(x) == y .
  5. Si el Type(x) es Boolean , devuelva el resultado de la comparación a ToNumber(x) == y .
  6. Si el Type(y) es Boolean , devuelva el resultado de la comparison x == ToNumber(y) .
  7. Si el Type(x) es String , Number o Symbol y el Type(y) es Object , devuelva el resultado de la comparación x == ToPrimitive(y) .
  8. Si el Type(x) es Objeto y el Type(y) es String , Number o Symbol , devuelva el resultado de la comparación ToPrimitive(x) == y .
  9. 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:

  • undefined representa 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.
  • null representa la ausencia intencional de un valor para un identificador o propiedad que ya se ha creado.

Son diferentes tipos de sintaxis:

  • undefined es 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 esconderse undefined de ese alcance (aunque las cosas todavía pueden estar undefined )
  • null es 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 undefined está sombreado por otro valor, es tan malo como sombrear Array o Number .
  • Evita establecer algo como undefined . Si desea eliminar una barra de propiedades de un objeto foo , delete foo.bar; en lugar.
  • El identificador de prueba de existencia foo contra undefined podría generar un error de referencia , en su lugar use typeof foo contra "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

6

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
6

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
6

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

Igualdad abstracta (==)

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) es true , para cualquier valor x
  • Simetría : Object.is(x, y) es true si, y solo si, Object.is(y, x) es true , para cualquier valor de x e y .
  • Transitividad : si Object.is(x, y) y Object.is(y, z) son true , Object.is(x, z) también es true , para cualquier valor de x , y y z .

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) es true , para cualquier valor x
  • Simetría : [x].includes(y) es true si, y solo si, [y].includes(x) es true , para cualquier valor de x e y .
  • Transitividad : si [x].includes(y) y [y].includes(z) son true , entonces [x].includes(z) también es true , para cualquier valor de x , y , y z .

Comparación de igualdad estricta

Se comporta como SameValue, pero

  • Considera que +0 y -0 son iguales.
  • Considera NaN diferente 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 === y es true si, y solo si, y === x is verdadero , for any values x and y`.
  • Transitividad : si x === y y y === z son true , entonces x === z también es true , para cualquier valor x , y , y z .

Pero no es una relación de equivalencia porque

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:

  • undefined y null se 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 == y es true si, y solo si, y == x es true , para cualquier valor x e y .

Pero no es una relación de equivalencia porque

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.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow