This behaviour is in the specification for The Abstract Equality Comparison Algorithm
From the specification
The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:
If Type(x) is the same as Type(y), then ...
...
If x is null and y is undefined, return true.
- If
x is undefined and y is null, return true.
- If
Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
- If
Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
- If
Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
- If
Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
- If
Type(x) is either String or Number and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).
- If
Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.
- Return false.
As undefined and a number (0) is not of the same type, it's only in the third point where it mentions what to do if the left hand side is undefined.
Then, if the right hand side is null, it returns true, any other value, and it goes straight to 10., which says "return false".
1and2are both truthy, would you expect1 == 2to betrue?undefined != 0and I guess that's just how it is. See there for the complete list of JS comparisons: dorey.github.io/JavaScript-Equality-Table