JavaScript == is strange. OR NOT?

So many times I have had doubts regarding some problem and I go to StackOverflow for finding their solutions. Since I am more into JavaScript than any other programming language these days, I started noticing one thing. People, a lot of times say: JavaScript is broken.

Well yes, I too believe that. We have so many methods to increase or decrease the size of an array: push, pop, unshift, shift, slice, splice, concat, filter. But, we don’t have a dedicated function to insert or delete an element at a particular index in an array. Every time you want to insert or delete, you have to look which will be the best method in this situation…

Anyways, this blog is not about finding loopholes but explaining why some of them are like so.

What this blog is not?

This blog is not a tutorial where I will teach you what happens behind the scenes in JS. Following are just my observations to understand things in a better and easier way. Please do not follow them blindly. I have done some research regarding the topic. I have compiled those learnings along with my own observations. Please enjoy the read. :)

The inspiration for this blog. The meme.

I saw this meme one day while reading a blog on medium and I was fascinated by this idea. At first, I thought: “Wow! JavaScript is defying the laws of maths”. But then, I processed the three statements and understood.

Let me explain.

We, by default, understand that when we use ==, javascript compares the values. But do we know what will be the output in each case? If you want to know, start reading the points.

1. JS checks if the values around == are boolean or not? If both values are boolean, they are evaluated accordingly.

2. If a value is not boolean, JS decides whether they are falsy or not. Falsy values are:

If both values are falsy, we get true.

3. If any value is truthy. If one of the values are among boolean, number, string or any other primitive type AND the other value is anything that can be converted to a string, then both are converted to a string and then compared.

For example,

(The steps are arrow separated in the following paragraph)

None of them is boolean → 0 is falsy but ‘0’ is truthy → 0 is number type and ‘0’ is a string type. Both are primitive. Both are converted to string → ‘0’ == ‘0’ → true. Yayy. We got the answer.

4. What if one is primitive and other is non-primitive? Then if non-primitive can be converted to string, i.e. toString() method is implemented for that object, the value is converted to a string before the primitive value and then compared.

None of them is boolean → 0 is falsy but [] is truthy → 0 is primitive but [] is object type (non-primitive) → [] has toString() method. JS converts [] to a string which gives an empty string (‘’) → 0 == ‘’ → None of them is boolean → 0 is falsy and ‘’ is falsy → true. Yayy got the answer.

None of them is boolean → None is falsy → ‘0’ is primitive but [] is not → [] has toString() method. JS converts [] to a string which gives an empty string (‘’) → ‘0’ == ‘’ → None of them is boolean → ‘’ is falsy but ‘0’ is truthy → false. Yayy got the answer again.

I was able to explain this one very intelligently (pat on my back). It also explains my next screenshot.

How am I considering an empty array to be true?

As you can see, in the first statement, it appears that an empty array is truthy. That is why it gives false when we apply the not operator. But then in the second statement, JS tells me it is not. Then I may start to think, “Okay it may neither be true or false. But then in the third statement, JS says, you are again wrong, it is false. And I am like, “Wow! will someone tell me what is going on here.”

Okay, it is simple. Let’s follow the steps that I explained above.

In the first line, empty array appears to be true. That’s fine.

In the second line, one of the values is boolean (false) → [] is not falsy → [] is not primitive → [] has toString() method. JS converts [] to a string which gives an empty string (‘’) → ‘’ == false → true.

See. That was simple. And we can similarly evaluate the third statement.

5. What if one is primitive and other is not primitive and non-primitive value also does not contain toString method? Then JS just gives a false.

As you can see, an object is a truthy value, and it is not even directly comparable to any value other than an object. That is why I stored it in a variable first. Now, as I said, it always gives a false whether we compare it to a boolean or any other value which does not have the same reference.

6. If both of them are non-primitive, then they are simply compared by reference.

In the first comparison, both objects look the same, but they are at different reference. Then I created three variables having the same values. But only a and c have the same reference. That is why only the last statement is true.

Hoof! This one was long. I may add other such situations in future.

If you know anything similar, please write them in comments.

Web UI developer in Edelweiss.