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 completeness, 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