I expect the result of
console.log(a && b);
to be false
and not null
as it shown in the example.
In many languages with &&
and ||
operators (or AND
and OR
), the result is always a boolean, yes.* But JavaScript's &&
and ||
are more useful than that: Their result is their left-hand operand's value or their right-hand operand's value, not coerced to boolean.
Here's how &&
works:
Evaluate the left-hand operand.
If the value is falsey (coerces to false
when we make it a boolean), return the value (not the coerced value)
If the value from #2 is truthy, evaluate and return the right-hand value (uncoerced)
The falsey values are null
, undefined
, 0
, ""
, NaN
, and of course, false
. Everything else is truthy.
So for instance
console.log(0 && 'hi'); // 0
...shows 0
because 0
is falsey. Note it resulted in 0
, not false
. Similarly, the result here:
console.log(1 && 'hello'); // hello
...is 'hello'
because the right-hand side isn't coerced at all by &&
.
||
works similarly (I call it the curiously-powerful OR operator): It evaluates the left-hand side and, if that's truthy, takes that as its result; otherwise it evaluates the right-hand side and takes that as its result.
The only time you get true
or false
from &&
or ||
is if the selected operand is already a boolean.
* Of course, many (but not all) of those languages (Java, C#) also require that the operands to &&
and ||
already be booleans. C's an exception, it does some coercion, but still has the result of the operands as a boolean (or if you go back far enough, an int that will be 1 or 0).