How __proto__ works when an object is created using Object.create (null)

Consider the following javascript code

var a = Object.create(null); a.foo = 1; var b = Object.create(a); console.log(b.foo); //prints 1 console.log(b.__proto__); //prints undefined b.__proto__ = null; console.log(b.__proto__); //prints null console.log(b.foo); //prints 1 

Can someone explain how object b accesses the property “foo” a even after setting b.__proto__ to null? What is the internal link that is used to access property a ?

I tried searching through SO for possible explanations, but could not find an explanation for this specific Javascript behavior.

+7
javascript inheritance prototype prototype-chain
source share
2 answers

Your problem is that you are using the deprecated __proto__ property , which is getter / setter on Object.prototype , but your objects are not inherited from it, so it is first undefined , and assignment creates a standard property called __proto__ .

Use the correct Object.getPrototypeOf / Object.setPrototypeOf and the code will do what you expect:

 var a = Object.create(null); a.foo = 1; var b = Object.create(a); console.log(b.foo); // 1 console.log(Object.getPrototypeOf(b)); // {foo:1} - a Object.setPrototypeOf(b, null); console.log(Object.getPrototypeOf(b)); // null console.log(b.foo); // undefined 
+6
source share

The answer to this question is @Bergi. Here is a detailed answer what happens in case of __proto__

 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 means that __proto__ is only present in Object.prototype .

 Object.getOwnPropertyDescriptor(Object.prototype,"__proto__") //{enumerable: false, configurable: true, get: ƒ, set: ƒ} 

__proto__ is a getter setter that should return an internal reference to the parent object, something like

 get __proto__(){return this.hidden_internal_link_to_parent;} 

Case b.__proto__ : - b does not have the __proto__ property, so it goes through the [[prototype]] chain to a , then to a parent, and finally to Object.prototype . Object.prototype have __proto__ and it returns the link b parent, which is a .

Case d.__proto__ : - d reference to Object.prototype broken (d --parent → c and c - parent → null). So d.__proto__ undefined. But d has an internal reference to c , which can be accessed by Object.getPrototypeOf(d) .

+2
source share

All Articles