In all of the JavaScript operator precedence charts I can find (like this one and this one), the logical AND (&&
) has slightly higher precedence to the logical OR (||
).
I can't seem to figure out an expression where the result is different than it would be if they had the same precedence. I figure there must be some way for it to matter or they'd be listed as having the same precedence if it didn't.
For example:
0 || 2 && 0 || 3
is 3
, but it doesn't matter how I slice that up, it's always going to be 3
:
(0 || 2) && 0 || 3
0 || (2 && 0) || 3
(0 || 2 && 0) || 3
0 || 2 && (0 || 3)
0 || (2 && 0 || 3)
If I make that first 0
something else (like 4
), the result is always 4
because the first ||
doesn't even look at the right-hand side. If I swap the 0
and 3
in the last ||
around, the result remains 3
.
The closest I've e is
0 || false && "" || NaN
...which is NaN
, whereas
0 || false && ("" || NaN)
...is false
, but I think that's explained purely by the left-to-right semantics, not by &&
being higher precedence.
I must just be missing it, for what expression does it matter that &&
has a higher precedence than ||
?
In all of the JavaScript operator precedence charts I can find (like this one and this one), the logical AND (&&
) has slightly higher precedence to the logical OR (||
).
I can't seem to figure out an expression where the result is different than it would be if they had the same precedence. I figure there must be some way for it to matter or they'd be listed as having the same precedence if it didn't.
For example:
0 || 2 && 0 || 3
is 3
, but it doesn't matter how I slice that up, it's always going to be 3
:
(0 || 2) && 0 || 3
0 || (2 && 0) || 3
(0 || 2 && 0) || 3
0 || 2 && (0 || 3)
0 || (2 && 0 || 3)
If I make that first 0
something else (like 4
), the result is always 4
because the first ||
doesn't even look at the right-hand side. If I swap the 0
and 3
in the last ||
around, the result remains 3
.
The closest I've e is
0 || false && "" || NaN
...which is NaN
, whereas
0 || false && ("" || NaN)
...is false
, but I think that's explained purely by the left-to-right semantics, not by &&
being higher precedence.
I must just be missing it, for what expression does it matter that &&
has a higher precedence than ||
?
- just making a guess: as a fallback maybe? – maioman Commented May 1, 2015 at 10:36
-
4
true || false && false
– Ôrel Commented May 1, 2015 at 10:36
4 Answers
Reset to default 6true || false && false
is true
(true || false) && false
is false
true || (false && false)
is true
If they had the same precedence and were left-associative, then e.g. the expression
1 || 0 && 2
would be
((1 || 0) && 2) // evaluates to 2
instead of the
(1 || (0 && 2)) // evaluates to 1
that we get from the "usual" precedence rules.
For your structure … || … && … || …
(which would be (((… || …) && …) || …)
instead of normal ((… || (… && …)) || …)
), you'd get different results for values like 0 0 1 0
.
Why does the logical AND have slightly higher precedence to the logical OR?
So that the canonical form of boolean expressions, the disjunctive normal form, does not need any parenthesis.
Example:
1 || 0 && 0
-> (1 || 0) && 0
-> (1) && 0
-> 0
1 || 0 && 0
-> 1 || (0 && 0)
-> 1 || (0)
-> 1
It's fun to answer the question algebraically:
(x | y) & z ≠ x | (y & z)
Expanding out the first bracketed term:
(x & z) | (y & z) ≠ x | (y & z)
Since y & z is equal to itself, the difference must e from:
x & z ≠ x
which is false if x = false so x = true, giving
true & z ≠ true
or
z ≠ true
So z = false.
Substituting x = true, z = false back into the original expression:
(true | y) & false ≠ true | (y & false)
So either value of y demonstrates the difference.