Why does `false && true || true` evaluate to true?
Solution 1
Your confusion all comes down to a misunderstanding of precedence.
A mathematical analogue would be "Zero multiplied by anything equals zero." Consider the following expression:
0 x 100 + 5
In any programming language, or a decent calculator, this evaluates to 5. The "zero times anything" axiom is true - but the "anything" in this case is 100
, NOT 100 + 5
! To see why, compare it to this:
5 + 0 x 100
It doesn't matter whether you add the 5 at the beginning or the end - the operator precedence rules remove ambiguity from the statement.
In JavaScript boolean logic, &&
has higher precedence than ||
. Since each operator is commutative, writing
false && true || true
is exactly the same as writing
true || false && true
Solution 2
You are looking at precedence wrong.
&& is done first, then || so what it looks like is how you wrote it:
(false && true) || true
So the MDN link is correct.
Solution 3
The language works by parsing an expression into abstract syntax tree. Your expression false && true || true
gets parsed into this:
||
/ \
&& true
/ \
false true
Only after building the AST, the short-circuited evaluation can take place. The
false && anything is short-circuit evaluated to false.
quote applies only to a valid sub-tree where false
and anything
are subtrees of &&
node, like this:
&&
/ \
false true
which means only the false && true
gets short-ciruit evaluated to false
and resulting false || true
is evaluated to true
Solution 4
Let's put it this way. Somebody who wrote this MDN article phrased it quite badly/did small mistake
As you pointed out it says:
false && anything is short-circuit evaluated to false.
And any reasonable person would assume that anything is logical expression of any complexity. However, this would be wrong reading (contradicting to boolean logic rules).
false && true || true == true
Two other answerers explained already why it's so. It's just an order of logical operators && and ||. First && is handled, next || is handled
Now, getting back to bad phrasing. What they should have said is following. Please notice additional parenthesis which I added.
false && (anything) is short-circuit evaluated to false.
I am using here parenthesis as a way to show that the rest of logical expression should have been evaluated independently of "false" part. If it's evaluated independently then short-circuiting it works fine because false && == false.
However, as soon as we have some expression which can't be evaluated independently then original phrasing doesn't work.
As example false && true || true
can't be evaluated independently, because of order or logical operations. However false && doSomething()
can.
Solution 5
JavaScript will parse this expression this way:
1) false && true //evaluates to false
2) false || true //equals true. The first false is the result above
It's easy to trace how JavaScript parse this whole expression this way:
(function(){alert(1); return false; })() &&
(function(){alert(2); return true; })() ||
(function(){alert(3); return true; })()
Kyle Falconer
I am a Software Engineer for Hopper with a Bachelor of Science in Computer Science from Missouri State University. Any opinions expressed by me are my own and not representative of Amazon's. I also do photography.
Updated on June 05, 2022Comments
-
Kyle Falconer almost 2 years
According to MDN Logical Operators page:
false && anything is short-circuit evaluated to false.
Given this information, I would expect
false && true || true
to evaluate to false. However, this is not the case. The expected result (false
) is only given when the statement is written like:false && (true || true)
A coworker and I have tried to work this out and the closest thing we could come up with is that the statement is being evaluated by order of precedence. According to the MDN Operator Precedence
logical-and
has a higher precidence overlogical-or
, suggesting that the condition is evaluated as iffalse && true
were a single statement, which then moves on to determine the boolean condition offalse || true
which is thentrue
. Written out, this would be:(false && true) || true
Something is wrong here. It's either the documentation, the JavaScript parsing logic, or my interpretation.
Edit:
I've added a bounty because none of the answers given truly understand the question. As stated above: the MDN Logical Operators page states exactly: "false && anything is short-circuit evaluated to false."
"anything" means "anything"!