2

null in JS is considered as an object. typeof null == "object" //true

Then why does null not have a __proto__. All objects should have a __proto__ in JS

var n = null;
console.log(n.__proto__);   //Cannot read property '__proto__' of null`

Can someone provide a detailed answer?

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143

3 Answers3

6

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__);
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
3

typeof null == "object" is a mistake, it's not actually an object. See why is typeof null "object"? for more details about why typeof considers it to be an object.

Konrad Borowski
  • 11,584
  • 3
  • 57
  • 71
0

From MDN web docs:

A primitive (primitive value, primitive data type) is data that is not an object and has no methods. In JavaScript, there are 6 primitive data types: string, number, boolean, null, undefined, symbol (new in ECMAScript 2015).

Most of the time, a primitive value is represented directly at the lowest level of the language implementation.

All primitives are immutable, i.e., they cannot be altered. It is important not to confuse a primitive itself with a variable assigned a primitive value. The variable may be reassigned a new value, but the existing value can not be changed in the ways that objects, arrays, and functions can be altered.

https://developer.mozilla.org/en-US/docs/Glossary/Primitive

Furthermore:

In the first implementation of JavaScript, JavaScript values were represented as a type tag and a value. The type tag for objects was 0. null was represented as the NULL pointer (0x00 in most platforms). Consequently, null had 0 as type tag, hence the bogus typeof return value.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof#null