null in JS is considered as an object. typeof null == "object" //true
As already mentioned, null is actually a primitive value (like undefined, a Boolean value, a String value, a Number value, or a symbol) . But the language spec dictates that typeof null returns the string "object". (Similarly the specification dictates to return "function" for function objects instead of "object", like it does for array objects)
But that's only one half of the story.
Then why does null not have a __proto__
You might be wondering:
Why can I access the protoype of a string value ("foo".__proto__) but not null if both are primitive values ?
That's because Booleans, Strings and Numbers have object equivalents (e.g. new String("foo")) and when you try to access a property on a boolean/number/string primitive, they are internally converted to an object value
console.log("foo".slice)
// does `new String("foo").slice` internally
However for undefined and null, no such object equivalents exist, hence the error.
try {
console.log(null.foo);
} catch(e) {
console.log(e.message);
}
try {
console.log(undefined.foo);
} catch(e) {
console.log(e.message);
}
All objects should have a __proto__ in JS
Not necessarily. It is possible to create objects without a prototype via Object.create:
const obj = Object.create(null);
console.log(obj.__proto__);