How does __proto__ work when object is created with Object.create(null)

喜你入骨 提交于 2021-02-04 17:36:06

问题


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 anyone explain how object b is accessing the "foo" property of a even after setting b.__proto__ to null? What is the internal link which is used to access the property of a?

I tried searching through SO for possible explanations but couldn't find any explanation for this particular behaviour of Javascript.


回答1:


Your problem is that you are using the deprecated __proto__ property, which is a getter/setter on Object.prototype - but your objects don't inherit from that, so it's undefined at first and the assignment creates a standard property with the name __proto__.

Use the proper Object.getPrototypeOf/Object.setPrototypeOf instead 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



回答2:


Answer by @Bergi is correct. Here is in-depth answer what is happening 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

Which means __proto__ is only present in Object.prototype.

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

__proto__ is a getter setter which should return internal link to object parent something like

get __proto__(){return this.hidden_internal_link_to_parent;}

Case b.__proto__:- b doesn't have __proto__ property so it goes through [[prototype]] chain to a, then to a's parent and at last to Object.prototype. Object.prototype have __proto__ and it returns link of b's parent which is a.

Case d.__proto__:- d's link to Object.prototype is broken (d --parent-->c and c--parent-->null). So d.__proto__ is undefined. But d have internal link to c which can be accessed by Object.getPrototypeOf(d).



来源:https://stackoverflow.com/questions/45072853/how-does-proto-work-when-object-is-created-with-object-createnull

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!