Double equal comparison in Javascript

Erdogan Oksuz
Aug 22, 2019 · 4 min read

Double equal comparison in Javascript is quite different than other programming languages because of The Javascript Weakly-Typed. If you work with strongly-typed language for a long time this thing can be hard to understand for you. Javascript seen as uncontrolled and irregular. Many of memes and coding challenges in internet support this decision.

Let’s look at one of these:

Patrick and javascript if conditions.
Patrick and javascript if conditions.
Poor Patrick.

Let's start with the first case

0 == "0" // true

If you say something like this:

In Javascript double equals only checks values not types.

Yes, you are right but we will understand how works Javascript in these cases.

This code works like this:

0 == Number(“0”) // true

In these situations, Javascript engines run this algorithm Abstract Equality Comparison Algorithm (cool name).

When you use == this algorithm runs step by step until the result is found.

Our case stopped in the fourth step. It means:

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

When our case different like this:

0 == "1" // false

The result will be false because of the converted value is not equal to “0”.

If you want to have some fun check this out:

0 == “0000” // true// Because Number(“0000”) returns 0

Continue with the second case

0 == [] // true

This case is more complicated than above because the algorithm runs twice.

This code works like this:

0 == Number([].valueOf().toString()) // true

In this case, we met primitive types. Algorithm stopped our case in the eighth step. It means:

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

It runs again and our case stopped in the fourth step it means:

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

If you check Abstract Equality Comparison Algorithm you can see ToPrimitive(y) method for object comparisons. This method converts our object to a primitive value. We cannot run manually ToPrimitive() because it’s a native code but we can change this behavior with .valueOf(). You need to read MDN document carefully because important notes exist like this:

JavaScript automatically invokes it when encountering an object where a primitive value is expected.

If we do not change the .valueOf(), Javascript engines will automatically convert to default primitive value. The following note explains why toString() called after .valueOf()

Objects in string contexts convert via the toString() method, which is different from String objects converting to string primitives using valueOf. All objects have a string conversion, if only "[object type]". But many objects do not convert to number, boolean, or function.

Alright, this means we can override .valueOf() and return our value. The approach of the engine has changed against our object.

This example explains what we do:

Is it that possible a variable equals array, string and number? Yes.

Last case

"0" == [] // false

This code works like this:

0 == [].valueOf().toString()

Everything looks the same with the previous one, stopped our case in
eighth step. It means:

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

Next step is important because ToPrimitive() returns an empty string for empty arrays and our code works like this now:

"0" == ""

The algorithm runs again and it stopped the first step:

If Type(x) is the same as Type(y), then
d. If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions). Otherwise, return false.

ToPrimitive() converts our array to string. It means our types are the same now. Algorithm check values again then the result will be false because “0” not equal to “ ”.

Bonus

Previous examples contain Arrays not Object. When we try with same cases with Objects somethings can change.

0 == [] // true
0 == {} // false

If you ask yourself like this:

Why the first case is true but the second one is false?

The answer is so easy, this code works like this:

0 == Number([].valueOf().toString()) // true
0 == Number(({}).valueOf().toString()) // false
({}).valueOf().toString() returns "[object Object]"
Number("[object Object]") returns NaN
NaN means "Not A Number" and not equal to 00 == NaN // false

This code can change everything:

({}).valueOf().toString() // returns [object Object]

For this case MDN says:

If this method is not overridden in a custom object, toString() returns "[object type]", where type is the object type.

When you give a string to Number(), this method cannot convert given value to a number and returns NaN.

That means Not A Number and is not equal to 0.

0 == NaN // false

We can create fun things for this, now all Objects equals to “yey” but this will be break somethings 😅.

Object.prototype.valueOf = function () {
return "yey"
}
"yey" == {} // true

You will see more complicated and absurd memes. Javascript is a Weakly-Typed language. It means every comparison automatically made by engines with algorithms but offers controls like === equality. If you see a complex case like the previous examples, official documentations like ECMAScript and MDN can explain everything and they can help to understand how to work Javascript.

Trendyol Tech

Trendyol Tech Team

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store