The Real Reason Why Empty Arrays Evaluate to True in JavaScript

When an empty array ([]) is cast to a boolean in JavaScript it equals true because it is an object, and all objects are cast to true. This is due to the fact that object variables are merely references to the location of the object which is a truthy value.

Boolean([]); // true for ALL arrays Boolean(new Array()); // same as above, true for ALL arrays Boolean(new Date()); // true for ALL date objects Boolean(new String()); // true for ALL string objects
Code language: JavaScript (javascript)

At first this might seem contradictory because an empty string ("") evaluates to false when cast to a boolean (Boolean("") === true). But the reason is because an empty string is a primitive, not an object. If you create the string as a String object then it will always evaluate to true, just like with an Array object.

Boolean("") // false, this is a string primitive Boolean(new String()) // true, this is a String *object*
Code language: JavaScript (javascript)

So this behavior is strange indeed, but at least it is consistent in that all objects are cast to true.

Another example of how JavaScript is at least consistently inconsistent:

Boolean(0) // false, this is a number primitive Boolean(new Number(0)) // true, this is a Number *object)
Code language: JavaScript (javascript)

But this is where it gets weird… if you evaluate an empty array in a conditional without explicitly casting it to a boolean, then it will be false!

[] == false // this is true! [] === false // this is false, since it is a strict comparison Boolean([]) === false // this is false
Code language: JavaScript (javascript)

This behavior is due to how comparisons are done in JavaScript. To compare [] with false, the JavaScript engine must first convert the array to a primitive. It doesn’t convert it to a boolean, but rather it converts it to a number primitive.

[] == false // true +[] // 0, which is false +false // also 0 +[] == +false // true
Code language: JavaScript (javascript)

It definitely seems inconsistent that when using Boolean([]) the array is cast to a boolean, but when doing [] == false it is cast to a number. But that is just how it is…

The Moral of The Story

So what is the takeaway here?

Well, you should always try to be explicit in your code about what you are actually trying to compare. It doesn’t really make sense to directly compare an array to a boolean, or a number, or anything else.

The only situation where it makes sense is you want to check if a variable is referencing the same object as another variable:

let arr1 = []; let arr2 = []; arr1 === arr2; // false, they are different arrays arr1 === arr1; // true, they are the same array
Code language: JavaScript (javascript)

Otherwise, if you are not checking the reference value of an object, you should explicitly convert it first to the appropriate value before making a comparison.

For example, are you wanting to check if the length of an array is 0? Then do that explicitly:

arr1.length === 0 // true, it is empty +arr1 === 0 // also true, but don't do this! it isn't clear
Code language: JavaScript (javascript)

By being more explicit in your code you can make it more readable and reduce the chance of bugs popping up.

References

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Equality

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *