¿Por qué los operadores lógicos (&& y ||) no siempre devuelven un resultado booleano?
¿Por qué estos operadores lógicos devuelven un objeto y no un booleano?
var _ = (obj.fn && obj.fn() ) || obj._ || ( obj._ = {} );
var _ = obj && obj._;
Quiero entender por qué devuelve el resultado de obj.fn()
(si está definido) O obj._
pero no un resultado booleano.
En JavaScript, ambos ||
y &&
son operadores lógicos de cortocircuito que devuelven el primer "valor lógico" completamente determinado cuando se evalúa de izquierda a derecha.
En la expresión X || Y
, X
primero se evalúa y se interpreta como un valor booleano. Si este valor booleano es "verdadero", se devuelve. Y Y
no se evalúa. (Porque no importa si Y
es verdadero o Y
falso, X || Y
ya está completamente determinado). Esa es la parte del cortocircuito.
Si este valor booleano es "falso", entonces todavía no sabremos si X || Y
es verdadero o falso hasta que lo evalúemos Y
y lo interpretemos también como un valor booleano. Luego se Y
devuelve.
Y &&
hace lo mismo, excepto que deja de evaluar si el primer argumento es falso.
La primera parte complicada es que cuando una expresión se evalúa como "verdadera", se devuelve la expresión misma. Lo cual cuenta como "verdadero" en expresiones lógicas, pero también puedes usarlo. Esta es la razón por la que ves que se devuelven valores reales.
La segunda parte complicada es que cuando una expresión se evalúa como "falso", en JS 1.0 y 1.1 el sistema devolvería un valor booleano de "falso"; mientras que en JS 1.2 devuelve el valor real de la expresión.
En JS false
, 0
, -0
, ""
, null
, y todos cuentan comoundefined
falsos .NaN
document.all
Por supuesto, aquí estoy citando valores lógicos para facilitar la discusión. Por supuesto, la cadena literal "false"
no es lo mismo que el valor false
y, por lo tanto, es verdadera.
En los términos más simples:
El ||
operador devuelve el primer valor verdadero y, si ninguno lo es, devuelve el último valor (que es un valor falso).
El &&
operador devuelve el primer valor falso y, si ninguno es falso, devuelve el último valor (que es un valor verdadero).
Es realmente así de simple. Experimente en su consola para comprobarlo usted mismo.
console.log("" && "Dog"); // ""
console.log("Cat" && "Dog"); // "Dog"
console.log("" || "Dog"); // "Dog"
console.log("Cat" || "Dog"); // "Cat"
var _ = ((obj.fn && obj.fn() ) || obj._ || ( obj._ == {/* something */}))? true: false
devolverá booleano.
ACTUALIZAR
Tenga en cuenta que esto se basa en mis pruebas. No debo confiar plenamente en mí.
Es una expresión que no asigna true
ni false
valora. Más bien asigna el valor calculado.
Echemos un vistazo a esta expresión.
Una expresión de ejemplo:
var a = 1 || 2;
// a = 1
// it's because a will take the value (which is not null) from left
var a = 0 || 2;
// so for this a=2; //its because the closest is 2 (which is not null)
var a = 0 || 2 || 1; //here also a = 2;
Tu expresión:
var _ = (obj.fn && obj.fn() ) || obj._ || ( obj._ = {} );
// _ = closest of the expression which is not null
// in your case it must be (obj.fn && obj.fn())
// so you are gettig this
Otra expresión:
var a = 1 && 2;
// a = 2
var a = 1 && 2 && 3;
// a = 3 //for && operator it will take the fartest value
// as long as every expression is true
var a = 0 && 2 && 3;
// a = 0
Otra expresión:
var _ = obj && obj._;
// _ = obj._
En la mayoría de los lenguajes de programación, los operadores &&
y ||
devuelven valores booleanos. En JavaScript es diferente .
O Operador:
Devuelve el valor del primer operando que se valida como verdadero (si lo hay), en caso contrario devuelve el valor del último operando (incluso si se valida como falso) .
Ejemplo 1:
var a = 0 || 1 || 2 || 3;
^ ^ ^ ^
f t t t
^
first operand that validates as true
so, a = 1
Ejemplo 2:
var a = 0 || false || null || '';
^ ^ ^ ^
f f f f
^
no operand validates as true,
so, a = ''
Y Operador:
Devuelve el valor del último operando que se valida como verdadero (si todas las condiciones se validan como verdaderas), en caso contrario devuelve el valor del primer operando que se valida como falso .
Ejemplo 1:
var a = 1 && 2 && 3 && 4;
^ ^ ^ ^
t t t t
^
last operand that validates as true
so, a = 4
Ejemplo 2:
var a = 2 && '' && 3 && null;
^ ^ ^ ^
t f t f
^
return first operand that validates as false,
so, a = ''
Conclusión:
Si desea que JavaScript actúe de la misma manera que otros lenguajes de programación, use Boolean()
funciones como esta:
var a = Boolean(1 || 2 || 3);// a = true