I was expecting the following comparison to give an error:
var A = B = 0;
if(A == B == 0)
console.log(true);
else
console.log(false);
but strangely it returns false
.
Even more strangely,
console.log((A == B == 1));
returns true
.
How does this "ternary" kind of comparison work?
I was expecting the following comparison to give an error:
var A = B = 0;
if(A == B == 0)
console.log(true);
else
console.log(false);
but strangely it returns false
.
Even more strangely,
console.log((A == B == 1));
returns true
.
How does this "ternary" kind of comparison work?
Share Improve this question edited May 11, 2014 at 19:51 Peter Mortensen 31.6k22 gold badges110 silver badges133 bronze badges asked Apr 10, 2014 at 6:45 laggingreflexlaggingreflex 34.6k36 gold badges143 silver badges200 bronze badges 2 |7 Answers
Reset to default 8First, we need to understand that a ==
comparison between a number and a boolean value will result in internal type conversion of Boolean value to a number (true
becomes 1
and false
becomes 0
)
The expression you have shown is evaluated from left to right. So, first
A == B
is evaluated and the result is true
and you are comparing true
with 0. Since true
becomes 1
during comparison, 1 == 0
evaluates to false
. But when you say
console.log((A == B == 1));
A == B
is true
, which when compared with number, becomes 1
and you are comparing that with 1 again. That is why it prints true
.
Assignment operators like = are right-associative: when there is a series of these operators that have the same precedence, they are processed right-to-left, so A = B = 0
is processed as A = (B = 0)
(B = 0
returns 0, so both A and B end up as 0).
Equality operators like == are left-associative: same-precedence operators are processed left-to-right. A == B == 0
is processed as (A == B) == 0
, and since A == B
is true (1), it becomes 1 == 0
, which is false (0).
Likewise, A == B == 1
is processed as (A == B) == 1
, which becomes 1 == 1
, which is true (1).
Source and more info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
First, A == B
returns true
, which is then compared to 0, true == 0
which returns false, or true == 1
which returns true.
It first checks your clause for A == B, which is true, than it starts checking true == 0, and 0 is false. So when you check A == B == 1, you check A==B, which is true, and true == 1. So then it returns true. If you really want to check all possibilities you should do something like this:
if((A==B) && (A==0))
console.log(true);
else
console.log(false);
if((A == B)&& (A== 0)&& (B==0))
console.log(true);
else
console.log(false);
You can work from left to right. In this case you first check if A == B, then you check if this equal to 0. So since A == B, this is true. So now it becomes (true == 0), which is false. If A=1, B=2, then (A == B == 0) would return true! This is because A == B is false and (false == 0) is true!
I believe you should just need 2 comparisons here, but they do need to be independent. So just check:
(A==B && B=0) ? {if true this happens} : {if False this happens}
This should work the same as a triple comparison, unless you have 3rd condition in case B === 0 and A !== 0
being different from A ===0 and B !==0
, eliminating the need for comparing A and 0.
if (A==0 && B==0)
– adeneo Commented Apr 10, 2014 at 6:47