Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do both "[] == true" and "![] == true" evaluate to false?

Tags:

javascript

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?

like image 579
aldenn Avatar asked Oct 06 '19 07:10

aldenn


People also ask

Why is [] == [] false?

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.

Why [] == ![] Is true in JS?

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.

Why does true == true return false?

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 ."

Why ![] Is false?

![] 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.


2 Answers

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:

  1. [] == true
  2. [] == 1
  3. "" == 1
  4. 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.

In more words:

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) + "`");
like image 80
nick zoum Avatar answered Oct 22 '22 15:10

nick zoum


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.

  1. For [] == true , rule 7 matches, so a result of [] == ToNumber(true) is returned i.e. false is returned.
  2. Reason you're getting the same result for ![] == 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
like image 31
pritam Avatar answered Oct 22 '22 13:10

pritam