Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do empty JavaScript arrays evaluate to true in conditional structures?

I was encountering a lot of bugs in my code because I expected this expression:

Boolean([]); to evaluate to false.

But this wasn't the case as it evaluated to true.

Therefore, functions that possibly returned [] like this:

// Where myCollection possibly returned [ obj1, obj2, obj3] or []
if(myCollection)
{
  // ...

}else
{
  // ...
}

did not do expected things.

Am I mistaken in assuming that [] an empty array?

Also, Is this behavior consistent in all browsers? Or are there any gotchas there too? I observed this behavior in Goolgle Chrome by the way.

like image 555
racl101 Avatar asked Oct 02 '13 20:10

racl101


People also ask

Why empty array is true in JavaScript?

Values not on the list of falsy values in JavaScript are called truthy values and include the empty array [] or the empty object {} . This means almost everything evaluates to true in JavaScript — any object and almost all primitive values, everything but the falsy values.

Why is an empty array true?

arrays are objects, objects are truthy. just ask for array. length, if not zero, it will be truthy. when you explicitly convert to Boolean, the array turns into an empty string first, then the empty string turns into false.

Does an empty array evaluate to TRUE?

Because Array is type of object , the fact that an empty Array is conversed to true is correct.

What does an empty array return in JavaScript?

This will return 0, as there are 0 items in the array.


4 Answers

From http://www.sitepoint.com/javascript-truthy-falsy/

The following values are always falsy:

  • false
  • 0 (zero)
  • 0n (BigInt zero)
  • "" (empty string)
  • null
  • undefined
  • NaN (a special Number value meaning Not-a-Number!)

All other values are truthy, including "0" (zero in quotes), "false" (false in quotes), empty functions, empty arrays ([]), and empty objects ({}).

Regarding why this is so, I suspect it's because JavaScript arrays are just a particular type of object. Treating arrays specially would require extra overhead to test Array.isArray(). Also, it would probably be confusing if true arrays behaved differently from other array-like objects in this context, while making all array-like objects behave the same would be even more expensive.

like image 66
Barmar Avatar answered Oct 22 '22 09:10

Barmar


You should be checking the .length of that array to see if it contains any elements.

if (myCollection) // always true
if (myCollection.length) // always true when array has elements
if (myCollection.length === 0) // same as is_empty(myCollection)
like image 32
DevlshOne Avatar answered Oct 22 '22 09:10

DevlshOne


While [] equals false, it evaluates to true.

yes, this sounds bad or at least a bit confusing. Take a look at this:

const arr = [];
if (arr) console.log("[] is truethy");
if (arr == false) console.log("however, [] == false");

In practice, if you want to check if something is empty, then check the length. (The ?. operator makes sure that also null is covered.)

const arr = []; // or null;
if (!arr?.length) console.log("empty or null")
like image 20
bvdb Avatar answered Oct 22 '22 10:10

bvdb


[]==false  // returns true

This evaluates to true, because of the Abstract Equality Algorithm as mentioned here in the ECMA Specification #Section 11.9.3

If you run through algorithm, mentioned above.

In first iteration, the condition satisfied is,

Step 7: If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).

Hence the above condition transforms to -> [] == 0

Now in second iteration, the condition satisfied on [] == 0:

Step 9: If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.

[] is an object, henceforth, on converting to primitive, it transforms to an empty string ''

Hence, the above condition transforms to -> '' == 0

In third iteration, condition satisfied, is:

Step 5: If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.

As we know, empty string, '' is a falsy value, hence transforming an empty string to number will return us a value 0.

Henceforth, our condition, will transform to -> 0 == 0

In fourth iteration, the first condition is satisfied, where the types are equal and the numbers are equal.

Henceforth, the final value of the [] == false reduces to 0 == 0 which is true.

Hope this answers your question. Otherwise, you can also refer this youtube video

like image 29
Abir Avatar answered Oct 22 '22 10:10

Abir