使用Object.create(null)创建对象时__proto__如何工作

时间:2017-07-13 06:23:18

标签: javascript inheritance prototype prototype-chain

考虑以下javascript代码

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

任何人都可以解释对象b如何访问" foo"即使将a设置为null,b.__proto__的属性?用于访问a

属性的内部链接是什么?

我尝试搜索SO以获取可能的解释,但无法找到有关Javascript特定行为的任何解释。

2 个答案:

答案 0 :(得分:7)

您的问题是您正在使用Object.prototype上的deprecated __proto__ property,这是undefined上的getter / setter - 但您的对象不会继承该对象,因此&# 39;首先是__proto__,分配会创建一个名为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 的标准媒体资源。

使用正确的Object.getPrototypeOf / Object.setPrototypeOf,代码将按预期执行:

rootView

答案 1 :(得分:2)

@Bergi的回答是正确的。以下是对__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

这意味着__proto__仅出现在Object.prototype

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

__proto__是一个getter setter,它应该返回对象父类的内部链接,比如

get __proto__(){return this.hidden_internal_link_to_parent;}

案例b.__proto__: - b没有__proto__属性,因此它通过[[prototype]]链到a,然后到{{1父母,最后到aObject.prototypeObject.prototype,并返回__proto__父母b的链接。

案例a: - d.__proto__d的链接已损坏(d - 父母 - > c和c - parent - > null )。所以Object.prototype未定义。但d.__proto__d的内部链接,c可以访问该链接。