I have noticed when using the OR logic or the nullish coalescing together with the includes method in a ternary fashion.
const result = 'Hello' || ['e', 'z'].includes('e') ? 'in-array' : 'not-in-array';
console.log(result) // 'in-array'
const result = 'Hello' ?? ['e', 'z'].includes('z') ? 'in-array' : 'not-in-array';
console.log(result) // 'in-array'
const result = 'Hello' || ['e', 'z'].includes('xx') ? 'in-array' : 'not-in-array';
console.log(result) // 'in-array'
const result = 'Hello' ?? ['e', 'z'].includes('xx') ? 'in-array' : 'not-in-array';
console.log(result) // 'in-array'
To make it work, you will have to add parentheses/round brackets to the right end condition.
const result = 'Hello' || (['e', 'z'].includes('e') ? 'in-array' : 'not-in-array');
console.log(result) // 'Hello'
const result = 'Hello' ?? (['e', 'z'].includes('z') ? 'in-array' : 'not-in-array');
console.log(result) // 'Hello'
Is this an expected behaviour? Why is this happening?
2
Answers
behavior you observed is due to operator precedence and the way JavaScript evaluates expressions. to control the evaluation order, you can use parentheses to explicitly define which parts of the expression should be evaluated first. this ensures that the ternary operator is evaluated as intended within the context of the logical OR
(||)
or nullish coalescing(??)
.different operators have different levels of precedence. operators with higher precedence are evaluated before those with lower precedence (just like in math)
Let’s look at the expression:
From the point of view of pure boolean logic, it’s ambiguous. One of those two operators must be performed first, but which should it be?
Is it this?
Or is it this?
In order to solve that ambiguity the language designers have decided that
&&
has a higher precedence than||
, and will therefore happen before operators of lower precedence.Which means that:
is the correct interpretation according to the language specification.
However, you can override that by using parentheses and this:
Will now do the
||
operator first, and then use the result of that as the left hand side of the&&
operator.Same for ternaries. The
||
and??
have higher precedence that the?
ternary operator.This means that this:
Is also ambiguous. Should
a || b
be the left hand side of the ternary? Or should the entire ternary be on the right side of||
? As you’ve noted, the resulting logic is different.What happens, is that it is interpreted as:
because
||
has higher precedence than?
does.And if you want a different order, then you can use parentheses to define that order:
This is just like basic math. What is the answer to this mathematical expression?
Is this
12
? Or is it11
? Without operator precedence, it’s ambiguous. With operator precedence that we all agree on, the answer is11
because×
has higher precedence than+
.And again, you can always override that with parentheses: