问题
Consider the following code.
console.log("All" && 1); // 1
console.log("All" || 1); // "All" ?
As you can see, the first expression, "All" && 1
, correctly evaluates to 1
. I expected the second expression, "All" || 1
, to evaluate to 1
too. However, it evaluates to "All"
. Why so?
In C, the second expression correctly evaluates to 1
.
#include <stdio.h>
int main() {
printf("%d\n", "All" && 1); // 1
printf("%d\n", "All" || 1); // 1
return 0;
}
Why does JavaScript behave differently?
回答1:
The logical operators in C always evaluate to boolean values. In C, the int 1
represents true
and the int 0
represents false
. That's the reason why both the expressions, "All" && 1
and "All" || 1
, evaluate to 1
. Both of them are logically true. For clarification, consider the following program.
#include <stdio.h>
int main() {
printf("%d\n", 20 && 10); // 1
printf("%d\n", 20 || 10); // 1
return 0;
}
In the above program, the expressions 20 && 10
and 20 || 10
still evaluate to 1
even though there is no 1
in those expressions. This makes sense because both those expressions are logically true. Hence, they evaluate to 1
which is equivalent to true
in JavaScript.
If JavaScript behaved the way C did then the expressions "All" && 10
and "All" || 10
would evaluate to the boolean value true
. However, that's not the way the logical operators behave in JavaScript. That's not to say that they are buggy.
Values in JavaScript have a notion of truthiness and falsity. For example, the values true
, "All"
, 10
, [10, 20]
, { foo: 10 }
, and x => 2 * x
are all truthy. On the other hand, the values false
, ""
, 0
, undefined
, and null
are falsy.
The logical operators of JavaScript don't always evaluate to boolean values like C does. Instead, they evaluate to one of their operands. The &&
operator evaluates to its left operand if it's falsy. Otherwise, it evaluates to the right operand. Similarly, the ||
operator evaluates to its left operand if it's truthy. Otherwise, it evaluates to the right operand.
Now, the value "All"
is truthy. Hence, "All" && 1
evaluates to the right operand (i.e. 1
) whereas "All" || 1
evaluates to the left operand (i.e. "All"
). Notice that both 1
and "All"
are truthy values, which means that they are equivalent to 1
(which represents truthiness) in C.
Hence, no. JavaScript is not buggy.
回答2:
Let's take some examples,
let a = [1,2,3];
console.log( 0 && a.b ); // return 0
console.log( 1 && a.b ); // return a type error.
Because in first console.log when JavaScript see 0 at first it's stop evaluate and return first value. Because in logical "and" if one condition is false the result became false. JavaScript save same memory by return it early. But in second case, first operand evaluate true. So result is dependent on second operand. So JavaScript cleaverly return second operand. As you see a.b is not exist so it return a type error. This is also happened with logical || or operator. Or operator return true if one of it's operand is true. In question about it returns all string. Because any non empty string evaluate the truth value. So no need more check. So simply return all string. Eventually with type conversation the "all" string became truth value.
来源:https://stackoverflow.com/questions/57752949/why-does-the-or-operator-in-javascript-behave-differently-than-in-c