¿Por qué no hay xor lógico en JavaScript?
javascript
xor
logical-operators
DarkLightA
fuente
fuente
!=
es que no puedes hacer lo mismoa ^= b
, porquea !== b
es solo el operador de desigualdad estricta .Javascript tiene un operador XOR bit a bit: ^
Puede usarlo con booleanos y dará el resultado como 0 o 1 (que puede convertir de nuevo a booleano, por ejemplo
result = !!(op1 ^ op2)
). Pero como dijo John, es equivalente aresult = (op1 != op2)
, que es más claro.fuente
true^true
es 0 yfalse^true
es 1.||
y&&
puede usarse como operadores lógicos en no booleanos (por ejemplo,5 || 7
devuelve un valor verdadero,"bob" && null
devuelve un valor falsey) pero^
no puede. Por ejemplo,5 ^ 7
es igual a 2, que es verdad.(true ^ false) !== true
lo que lo hace molesto con las bibliotecas que requieren booleanos realesa ^= true
alternar booleanos y falla en algunas máquinas como los teléfonos.No hay operadores booleanos lógicos reales en Javascript (aunque se
!
acerca bastante). Un operador lógico solo tomaríatrue
ofalse
como operandos y solo devolveríatrue
ofalse
.En Javascript
&&
y||
tomar todo tipo de operandos y devolver todo tipo de resultados divertidos (lo que sea que se introduce en ellos).Además, un operador lógico siempre debe tener en cuenta los valores de ambos operandos.
En Javascript
&&
y||
tomar un atajo perezoso y no evaluar el segundo operando en ciertos casos y con ello el abandono de sus efectos secundarios. Este comportamiento es imposible de recrear con un xor lógico.a() && b()
evalúaa()
y devuelve el resultado si es falso. De lo contrario, evalúab()
y devuelve el resultado. Por lo tanto, el resultado devuelto es verdadero si ambos resultados son verdaderos y falso de lo contrario.a() || b()
evalúaa()
y devuelve el resultado si es verdadero. De lo contrario, evalúab()
y devuelve el resultado. Por lo tanto, el resultado devuelto es falso si ambos resultados son falsos y, en caso contrario, verdadero.Entonces, la idea general es evaluar primero el operando izquierdo. El operando correcto solo se evalúa si es necesario. Y el último valor es el resultado. Este resultado puede ser cualquier cosa. Objetos, números, cadenas ... ¡lo que sea!
Esto hace posible escribir cosas como
o
Pero el valor de verdad de este resultado también se puede utilizar para decidir si un operador lógico "real" habría devuelto verdadero o falso.
Esto hace posible escribir cosas como
o
Pero un operador xor "lógico" (
^^
) siempre tendría que evaluar ambos operandos. Esto lo hace diferente a los otros operadores "lógicos" que evalúan el segundo operando solo si es necesario. Creo que es por eso que no hay xor "lógico" en Javascript, para evitar confusiones.Entonces, ¿qué debería pasar si ambos operandos son falsos? Ambos podrían ser devueltos. Pero solo uno puede ser devuelto. ¿Cúal? ¿El primero? O el segundo? Mi intuición me dice que devuelva los primeros, pero generalmente los operadores "lógicos" evalúan de izquierda a derecha y devuelven el último valor evaluado. ¿O tal vez una matriz que contiene ambos valores?
Y si un operando es verdadero y el otro operando es falso, un xor debería devolver el verdadero. ¿O tal vez una matriz que contiene el verdadero, para que sea compatible con el caso anterior?
Y finalmente, ¿qué debería pasar si ambos operandos son verdaderos? Esperarías algo falso. Pero no hay resultados falsos. Entonces la operación no debería devolver nada. Entonces tal vez
undefined
o ... ¿una matriz vacía? Pero una matriz vacía sigue siendo verdadera.Tomando el enfoque de matriz, terminaría con condiciones como
if ((a ^^ b).length !== 1) {
. Muy confuso.fuente
El XOR de dos booleanos es simplemente si son diferentes, por lo tanto:
fuente
Convierta valores en forma booleana y luego tome XOR bit a bit. También ayudará con valores no booleanos.
fuente
De encubierto a booleano y luego realizar xor como -
fuente
!!a ^ !!b
es equivalente a!a ^ !b
. Se podrían hacer argumentos sobre cuál es más fácil de leer.hay ... una especie de:
o más fácil de leer:
¿por qué? No sé.
porque los desarrolladores de JavaScript pensaron que sería innecesario ya que puede ser expresado por otros operadores lógicos ya implementados.
también podría tener gon con nand y eso es todo, puede impresionar cualquier otra operación lógica posible a partir de eso.
Personalmente, creo que tiene razones históricas que se basan en lenguajes de sintaxis basados en c, donde, por lo que sé, xor no está presente o al menos es extremadamente raro.
fuente
Sí, solo haz lo siguiente. Suponiendo que se trata de booleanos A y B, el valor de A XOR B se puede calcular en JavaScript utilizando lo siguiente
La línea anterior también es equivalente a la siguiente
Personalmente, prefiero xor1 ya que tengo que escribir menos caracteres. Creo que xor1 también es más rápido también. Solo está realizando dos cálculos. xor2 está realizando tres cálculos.
Explicación visual ... Lea la tabla a continuación (donde 0 representa falso y 1 representa verdadero) y compare las columnas 3 y 5.
! (A === B):
Disfrutar.
fuente
var xor1 = !(a === b);
es lo mismo quevar xor1 = a !== b;
!(2 === 3)
estrue
, pero2
y3
son sinceros, así2 XOR 3
debería serfalse
.Revisa:
Puedes imitarlo de esta manera:
fuente
¿Qué tal transformar el resultado int en un bool con doble negación? No tan bonito, pero realmente compacto.
fuente
B = ((!state1)!==(!state2))
B =!!(!state1 ^ !state2);
Además, ¿por qué tantos paréntesis?B = !state1 !== !state2;
O incluso puede abandonar la negación:B = state1 !== state2;
state1 !== state2
, entonces no necesita hacer ninguna conversión allí, ya que!==
es un operador lógico, no un bit a bit.12 !== 4
Es cierto'xy' !== true
también es cierto. Si usarías en!=
lugar de!==
, entonces tendrías que hacer casting.!==
y!=
siempre es booleano ... no estoy seguro de cuál es la distinción que estás haciendo allí, ese no es el problema. El problema es que el operador XOR que queremos es realmente la expresión(Boolean(state1) !== Boolean(state2))
. Para booleanos, "xy", 12, 4 ytrue
todos son valores verdaderos, y deben convertirse atrue
. así("xy" XOR true)
debería serfalse
, pero en("xy" !== true)
cambiotrue
, como usted señala. Entonces,!==
o!=
son (ambos) equivalentes a "XOR lógico" si y solo si convierte sus argumentos a booleanos antes de aplicar.En la función xor anterior, se obtendrá un resultado SIMILAR ya que xor lógico no es exactamente xor lógico, significa que resultará "falso para valores iguales" y "verdadero para valores diferentes" teniendo en cuenta la coincidencia de tipos de datos.
Esta función xor funcionará como xor real u operador lógico , lo que significa que resultará verdadero o falso de acuerdo con los valores de paso verdaderos o falsos . Use de acuerdo a sus necesidades
fuente
(!!x) === (!!y)
. La diferencia es un elenco a booleano.'' === 0
es falso, mientras quexnor('', 0)
es cierto.En mecanografiado (el + cambia a valor numérico):
Entonces:
fuente
!!(false ^ true)
funciona bien con booleanos. En mecanografiado, se requiere + para que sea válido!!(+false ^ +true)
.cond1 xor cond2
es equivalente acond1 + cond 2 == 1
:Aquí está la prueba:
fuente
La razón por la que no hay un XOR lógico (^^) es porque, a diferencia de && y || no da ninguna ventaja de lógica perezosa. Ese es el estado de ambas expresiones a la derecha y a la izquierda que deben evaluarse.
fuente
Aquí hay una solución alternativa que funciona con más de 2 variables y proporciona un recuento como bonificación.
Aquí hay una solución más general para simular XOR lógico para cualquier valor verdadero / falso, como si tuviera el operador en declaraciones IF estándar:
La razón por la que me gusta esto es porque también responde "¿Cuántas de estas variables son verdaderas?", Por lo que generalmente guardo previamente ese resultado.
Y para aquellos que desean un estricto comportamiento booleano-VERDADERO o de verificación, simplemente haga:
Si no le importa el recuento, o si le importa el rendimiento óptimo: simplemente use el xor bit a bit en los valores obligados a booleano, para la solución verdadero / falso:
fuente
Hola, encontré esta solución, para hacer y XOR en JavaScript y TypeScript.
fuente
Prueba este breve y fácil de entender
Esto funcionará para cualquier tipo de datos.
fuente
true == someboolean
no es necesario hacerlo , así que realmente, lo que has hecho es envolver los estrictos no iguales en una función.