¿Cuál es la diferencia entre & y && en JavaScript?

82

¿Cuál es la diferencia entre & y && en JavaScript?

Código de ejemplo:

var first  = 123;
var second = false;
var third  = 456;
var fourth = "abc";
var fifth  = true;
alert(first & second); // 0
alert(first & third);  // 72
alert(first & fourth); // 0
alert(first & fifth);  // 1

alert(first && second); // false
alert(first && third);  // 456
alert(first && fourth); // abc
alert(first && fifth);  // true

Parece que && es un "y" lógico que siempre me da el segundo valor si ambos son verdaderos.

Pero que es &?

(Por cierto, && parece ser "y" en Python; & parece ser & en Python).

Martín Thoma
fuente
Si se está preguntando por qué no usamos operaciones bit a bit en lugar de operadores lógicos, considere 4 & 1 = 0. Usando dos matrices de longitud 4 y 1; bit a bit: fruits.length & veggies.length === 0, y boolean: fruits.length && veggies.length === true.
Tom Anderson

Respuestas:

149

& es bit a bit Y

Este operador espera dos números y devuelve un número. En caso de que no sean números, se convierten en números.

¿Como funciona? Wikipedia tiene una respuesta: https://en.wikipedia.org/wiki/Bitwise_operation#AND

Nota: En Javascript, se desaconseja el uso de este operador , ya que no hay un tipo de datos entero, solo un punto flotante. Por lo tanto, los flotantes se convierten en números enteros antes de cada operación, lo que la hace lenta. Además, no tiene un uso real en aplicaciones web típicas y produce código ilegible.

Regla general: evitar. No lo use. Rara vez tiene lugar en un código JS fácil de mantener y leer.

&& es lógico Y

Espera dos argumentos y devuelve:

  • Primer término que se evalúa como falso
  • Último término de lo contrario (si todos son verdaderos)

Aquí hay unos ejemplos:

0 && false          0 (both are false-y, but 0 is the first)
true && false       false (second one is false-y)
true && true        true (both are true-y)
true && 20          20 (both are true-y)

Si solo lo usa en booleano, este es exactamente el operador AND de la lógica matemática.

&& encadenamiento de operadores

La razón por la que este operador se define como anteriormente es el encadenamiento de operadores. Puede encadenar este operador y seguir manteniendo las reglas anteriores.

true && 20 && 0 && 100          0 (it is the first false-y)
10 && 20 && true && 100         100 (last one, since all are true-y)

&& cortocircuito

Como puede verse en la definición, tan pronto como descubra que un término es falso, no debe preocuparse por los siguientes términos. Javascript incluso lleva esto un poco más allá, los términos ni siquiera se evalúan. A esto se le llama cortocircuito.

true && false && alert("I am quiet!")

Esta declaración no alerta nada y falsese devuelve. Por lo tanto, puede usar el &&operador como un reemplazo más corto de una declaración if. Estos son equivalentes:

if (user.isLoggedIn()) alert("Hello!")
user.isLoggedIn() && alert("Hello!")

Casi todos los compresores JS usan este truco para ahorrar 2 bytes.

Rok Kralj
fuente
5
&& no devuelve booleano en JavaScript.
Sanghyun Lee
1
AFAIK, &&devuelve el primer valor, si es falso-y, y el segundo valor en caso contrario.
duri
1
Respuesta completamente revisada.
Rok Kralj
Si devuelve el primer valor, entonces no entiendo cómo puedo ejecutar esto: if ($ ('# form1'). Parsley (). Validate () == true && $ ('# form2'). Persley () .validate () == true) {// hacer algo si ambos formularios son válidos} porque saldrá en la primera función si es falso y nunca validará el segundo formulario, ¿cómo ejecutar esa instrucción IF?
user991
1
@ user777 ¿No es irrelevante si el segundo formulario está validado o no si su operación solo debe ocurrir en ambas validaciones? Si el primer formulario falla, toda la operación no es válida. Sin embargo, esta es una pregunta completamente separada porque este hilo se trata de regresar , no de usar declaraciones if .
Ryan Williams
24

&es el bit a bit "y". Esto significa que si tiene dos números convertidos a binarios, el resultado es un número que tiene el 1dígito en las posiciones donde tienen ambos números 1.

  100011  //35
& 111001  //57
---------
  100001  //35 & 57 == 33
duri
fuente
-3

Para determinar si dos valores booleanos juntos son verdaderos o falsos, si desea verificar ambos (como la validación en la página web), puede usar el &operador. &es AND bit a bit.

Con el &&operador, una vez que encuentra que el primer valor es falso, finalizará la evaluación y no comprobará el segundo valor.

Jake Wayne
fuente
1
No usa AND ( &) bit a bit cuando trabaja con valores booleanos. Consulte las otras respuestas sobre el uso apropiado de este operador.
FtDRbwLXw6
@drrcknlsn, leí las otras respuestas pero la explicación aquí funciona muy bien, ¿podría proporcionar más información sobre su reclamo?
azerafati
1
@Bludream: La explicación en esta respuesta es incorrecta. No utiliza operadores bit a bit para comparaciones lógicas (booleanas). Utiliza operadores lógicos (booleanos). Hacen cosas diferentes (aunque similares), esperan diferentes entradas, producen diferentes salidas y tienen diferente precedencia de operadores.
FtDRbwLXw6
1
Estoy de acuerdo en que es una mala práctica, pero usar & con valores booleanos funcionará. false se evalúa como 0 y true se evalúa como 1. No veo nada que sea técnicamente incorrecto con esta respuesta, ya que "puede" usar &, simplemente no se recomienda.
dyoung
-3

Con todas las ideas elevadas y detalladas en todo momento, en su mayoría se han perdido la verdad de que hay una evaluación condicional en la que SOLO el single & funcionará. La respuesta práctica del lego que resolvió mi cabeza golpeando una cadena de instrucciones IF de MULTIPLE encadenado && cada! == a una condición estaba causando FALLO y necesitaba usar legítimamente el sencillo &. Agradezco a Jake Wayne (y Russ) por su respuesta injustamente rechazada que acertó dado que donde hay más de un && that! == ya ha cesado su evaluación y no procede más después de que se encuentra la primera evaluación == !. Con &&, cree que su trabajo está hecho después de que la primera evaluación muestre! == [eg. falso]. Mi código fallido era

IF ((sessionStorage.myLable !== "LableStringA") && (sessionStorage.myLable !== "LableStringB") && (sessionStorage.myLableZ !== "LableStringA") && (sessionStorage.myLableZ !== "LableStringB")) { ...)

Aquí, sustituyendo y usando correctamente un & por el &&, era prácticamente en el mundo real y técnicamente la respuesta correcta. Gracias de nuevo a Jake Wayne (y Russ) por la información y comprensión del código.

GladHeart
fuente
1
No recomiendo usar algo 'solo porque funciona' si no lo entiende. Simplemente se está preparando para problemas más adelante cuando termina no funcionando y no puede depurarlo. O peor aún, intentas usarlo en una entrevista de trabajo y te miran como ಠ_ಠ. Si sus condicionales no están evaluando cómo espera, tiene un error lógico. No hay razón para evaluar los 4 condicionales si el primero devuelve falso porque el condicional combinado nunca se puede evaluar como verdadero en ese caso
Brandon
Gracias Brandon. No cuestiono sus preocupaciones generales. Siempre difiero e instituyo la convención ===. Aquí, sin embargo, TODAS las cuatro evaluaciones fueron necesarias contrariamente a su último comentario bien intencionado. Las cuatro evaluaciones debían ser! == y se usaron en ese formato entre paréntesis. Fue la concatenación de && la que no funcionaría como esperaba la alta lógica. El uso de un solo & fue leído correctamente por los compiladores en todos los principales sistemas operativos que probé.
GladHeart
Como seguimiento de por qué parece y funciona elegantemente, estaría en la claridad de la respuesta falsamente menospreciada de Russ & Jake. Deben evaluarse las cuatro evaluaciones. El uso de && detiene / aborta cuando la primera evaluación es falsa. El uso del sencillo & le permite continuar evaluando necesariamente las tres condiciones restantes. Como dijo Russ & Jake, "Con el operador" && ", una vez que encuentra que el primer valor es falso, finalizará la evaluación y no comprobará el segundo valor". Considerando que, "si desea verificarlos [todos] (como la validación en la página web), puede usar el operador" & "." & "Es bit a bit Y"
GladHeart
1
Si necesita verificarlos todos, también puede estructurar su lógica como lo if (!(sessionStorage.myLable === "LableStringA" || sessionStorage.myLable === "LableStringB") || !(sessionStorage.myLableZ === "LableStringA" || sessionStorage.myLableZ === "LableStringB")) { // fail validation}que parece ser más claro en cuanto a lo que pretende (supongo que desea asegurarse de que los valores de myLable sean uno de los dos valores, o fallar la validación) . A menos que sus afecciones tengan efectos secundarios, no hay ninguna razón por la que deba evaluarlos todos. El operador funciona según lo previsto, pero su lógica se invirtió
Brandon
Ty por el seguimiento de Brandon. Con respeto, todavía pasa por alto la necesidad de las condiciones en mi caso donde buscar === podría ser una de las docenas de posibilidades en cada una de las cuatro validaciones. Simplemente, si ninguno de los cuatro no contiene un valor de marcador de página específico, recurro a ejecutar un script para compensar su falta. Los cuatro DEBEN mostrarse como == !. No es que "suponiendo que quiera asegurarse de que los valores de myLable sean uno de los dos valores", es de hecho que myLable es uno de los muchos en un pajar de posibilidades. Por lo tanto, la no equivalencia es una sola pregunta necesaria 4x.
GladHeart