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
".