Flanagan's O'Reilly JavaScript book states:
Unlike the && and || operators, the ! operator converts its operand to a boolean value [...] before inverting the converted value.
If those logical operators don't convert the operands to booleans, how can the expression be evaluated?
Flanagan's O'Reilly JavaScript book states:
Unlike the && and || operators, the ! operator converts its operand to a boolean value [...] before inverting the converted value.
If those logical operators don't convert the operands to booleans, how can the expression be evaluated?
Share Improve this question asked Sep 29, 2011 at 18:47 ppecherppecher 1,9884 gold badges19 silver badges30 bronze badges 1- See also JavaScript type conversion: (true && 1) vs (true | | 1) – Old Pro Commented Jun 2, 2013 at 16:46
4 Answers
Reset to default 11They do convert the values to boolean, but only to determine how to proceed in evaluating the expression. The result of the expression is not necessarily boolean (in fact, if neither of your operands are boolean, it will not give you a boolean):
var x = false || 'Hello' // gives you 'Hello'
var y = 0 && 1 // gives you 0, because 0 is "falsy" and short circuits
var z = 1 || 2 // gives you 1, because 1 is "truthy" and short circuits
Per specification, section 11.11: Binary Logical Operators:
The production [of evaluating &&
] ... is evaluated as follows:
- Let lref be the result of evaluating LogicalANDExpression.
- Let lval be GetValue(lref).
- If
ToBoolean(lval)
is false, return lval. - Let rref be the result of evaluating BitwiseORExpression.
- Return GetValue(rref).
The production [of evaluating ||
] ... is evaluated as follows:
- Let lref be the result of evaluating LogicalORExpression.
- Let lval be GetValue(lref).
- If
ToBoolean(lval)
is true, return lval. - Let rref be the result of evaluating LogicalANDExpression.
- Return GetValue(rref).
So internally the value is "converted to a boolean". However, since this is never exposed -- and the entire semantic explanation is an abstraction which can be/is "optimized out" -- the behavior of &&
and ||
can be simply explained through using truthy-and-falsy values (for which ToBoolean
covers: a truthy-value is one for which ToBoolean
returns true, all other values are falsy).
The logical table for &&
is:
a b result truthy any b falsy any a
The logic table for ||
is:
a b result truthy any a falsy any b
Note that either the evaluation of a
or b
is returned.
Happy coding.
For pleteness, from section 9.2:
The abstract operation ToBoolean
converts its argument to a value of type boolean as ...
- Undefined - false
- Null - false
- boolean (not Boolean object!) - The result equals the input argument (no conversion).
- number (not Number object!) - The result is false if the argument is +0, -0, or NaN; otherwise the result is true.
- string (not String object!) - The result is false if the argument is the empty String (its length is zero); otherwise the result is true.
- Object - true
The operands are interpreted as booleans for evaluating the expression, but the return value of && or || is always one of the operands.
For example:
true && 0 === 0, not false
1 || false === 1, not true
Because JavaScript has an idea of truthiness that covers more than booleans.