According to the explanation provided by @Bergi, let's delve into what is actually happening with the __proto__
scenario:
var a = Object.create({});
var b = Object.create(a);
b.__proto__===a; //true
var c = Object.create(null);
var d = Object.create(c);
d.__proto__===c; //false..confusion
Object.hasOwnProperty.call(d,"__proto__"); //false as expected
Object.hasOwnProperty.call(b,"__proto__"); //false ?
Object.hasOwnProperty.call(Object,"__proto__"); //false
Object.hasOwnProperty.call(Object.prototype,"__proto__"); //true
This clearly indicates that __proto__
exists only within Object.prototype
.
Object.getOwnPropertyDescriptor(Object.prototype,"__proto__")
//{enumerable: false, configurable: true, get: ƒ, set: ƒ}
The __proto__
essentially acts as a getter setter, returning an internal link to the object's parent, like so:
get __proto__(){return this.hidden_internal_link_to_parent;}
In the case of b.__proto__
- Since b
does not have the __proto__
property, it traverses through the [[prototype]]
chain to a
, then to a
's parent and finally to Object.prototype
. The latter has __proto__
which returns the link of b
's parent, which is a
.
Now, in the case of d.__proto__
- The link from d
to Object.prototype
is broken (d --parent-->c and c--parent-->null). Hence, d.__proto__
is undefined. However, d
does possess an internal link to
c</code, retrievable via <code>Object.getPrototypeOf(d)
.