I have two statements like this. Why do they both evaluate to false
?
console.log([] == true)
console.log(![] == true)
If [] == true
is false
shouldn't ![] == true
result to true
?
Alternative expression Because [] creates a new array, so you are comparing one array object with another array object. It's not the contents of the arrays that is compared, the object references are compared. They are not equal because it's not the same object instance.
Double equals, == , performs an amount of type coercion on values before attempting to check for equality. So arr == arr returns true as you'd expect as what you are actually checking is if [] == [] and both sides of the equation are of the same type.
Because they don't represent equally convertible types/values. The conversion used by == is much more complex than a simple toBoolean conversion used by if ('true') . So given this code true == 'true' , it finds this: "If Type(x) is Boolean , return the result of the comparison ToNumber(x) == y ."
![] evaluates to false because the reference is truthy. [] can be converted to a number ( 0 in this case ) which is a falsy value. Therefore: the condition passes as equal.
It's the way coercion works.
The first step of coercion is to convert any non primitive types to primitive types, then using a set of rules convert the left, right or both sides to the same type. You can find these rules here.
In your case [] == true
, would pass through these 4 steps:
[] == true
[] == 1
"" == 1
0 == 1
Whereas based on operator precedence the !
in ![] == true
is executed first so the expression is converted to false == true
which is obviously false
.
You can try the live demo by Felix Kling to better understand how the sameness operator works.
The value ![]
is false
, because []
is an Object (arrays are objects) and all objects, not including null
, are truthy. So any array, even if it is empty will always be a truthy, and the opposite of a truthy is always false
. The easiest way to check if a value is a truthy is by using !!
.
console.log("![]: " + ![]);
console.log("!![]: " + !![]);
When you are using a loose comparison (using ==
instead of ===
) you are asking the JavaScript engine to first convert the values into the same type and then compare them. So what happens is the values get converted according to a set of rules, once they are the same type, they get compared though the same process as a strict equality check (===
). The first change that []
goes through is to get converted to a string, the string version of an empty array is an empty string ""
, the empty string is then converted to a number, the numeric value of an empty string is 0
, since the numeric value of true
is 1
and 0
!= 1
, the final output is false
.
console.log("[] == true => `" + ([] == true) + "`");
console.log("String([]) => `" + String([]) + "`");
console.log("Number('') => `" + Number("") + "`");
console.log("Number(true) => `" + Number(true) + "`");
As per the Abstract Equality Comparison Algorithm - http://es5.github.io/#x11.9.3
Types of x and y are checked when
x == y
is to be checked.If no rule matches, a false is returned.
[] == true
, rule 7 matches, so a result of [] == ToNumber(true)
is returned i.e. false
is returned. ![] == true
, because ![]
returns false
, and false == true
returns false
.To get opposite result for your second operation, add a precedence (i.e. wrap) to your expression with braces.
console.log(!([] == true)); // returns true
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With