What's the difference between == and === ?

The difference between ==(abstract equality) and ===(strict equality) is that the == compares by value after coercion and === compares by value and type without coercion.

Let's dig deeper on the ==. So first let's talk about coercion.

coercion is the process of converting a value to another type. As in this case, the == does implicit coercion. The == has some conditions to perform before comparing the two values.

Suppose we have to compare x == y values.

  1. If x and y have same type. Then compare them with the === operator.
  2. If x is null and y is undefined then return true.
  3. If x is undefined and y is null then return true.
  4. If x is type number and y is type string Then return x == toNumber(y).
  5. If x is type string and y is type number Then return toNumber(x) == y.
  6. If x is type boolean Then return toNumber(x) == y.
  7. If y is type boolean Then return x == toNumber(y).
  8. If x is either string,symbol or number and y is type object Then return x == toPrimitive(y).
  9. If x is either object and x is either string,symbol Then return toPrimitive(x) == y.
  10. Return false.

Note: toPrimitive uses first the valueOf method then the toString method in objects to get the primitive value of that object.

Let's have examples.

x y x == y
5 5 true
1 '1' true
null undefined true
0 false true
'1,2' [1,2] true
'[object Object]' {} true

These examples all return true.

The first example goes to condition one because x and y have the same type and value.

The second example goes to condition four y is converted to a number before comparing.

The third example goes to condition two.

The fourth example goes to condition seven because y is boolean.

The fifth example goes to condition eight. The array is converted to a string using the toString() method which returns 1,2.

The last example goes to condition ten. The object is converted to a string using the toString() method which returns [object Object].

x y x === y
5 5 true
1 '1' false
null undefined false
0 false false
'1,2' [1,2] false
'[object Object]' {} false

If we use the === operator all the comparisons except for the first example will return false because they don't have the same type while the first example will return true because the two have the same type and value.