为什么 Object.create(null) 的 __proto__ 未定义?

问题描述 投票:0回答:1

在阅读 Javascript 原型时,我遇到了这种我无法解释的行为。我正在 chrome 的控制台(V8)中测试它。

var fruit = {taste:'good'};
var banana = Object.create(fruit);
console.log(banana.taste); //"good"
console.log(banana.__proto__); //Object {taste: "good"}
console.log(Object.getPrototypeOf(banana)); //Object {taste: "good"}

到目前为止,一切都如预期。 但是如果我这样做:

var drink = Object.create(null);
Object.defineProperty(drink, 'taste', {value:"nice"});
var coke = Object.create(drink);
console.log(coke.taste); //"nice"
console.log(coke.__proto__); //undefined
console.log(Object.getPrototypeOf(coke)); //Object {taste: "nice"}

然后

coke.__proto__ === undefined
。为什么是第二种情况
undefined

javascript prototype v8
1个回答
13
投票

我曾经针对此行为提出了问题,但它作为符合标准的行为而被关闭。根据问题关闭原因:

这正在按规定工作。 ES6

__proto__
是在 Object.prototype 上定义的 getter。对于原型链中没有该属性的对象,它是不可访问的(就像 hasOwnProperty 不可访问一样)。您需要使用 Object.getPrototypeOf 来代替。

这确实是真的:ES6 第 B.2.2.1 节定义了

Object.prototype.__proto__
;因此,
__proto__
属性继承自
Object.prototype
。但是,您的
drink
对象是使用
Object.create(null)
创建的,因此它的原型链中没有
Object.prototype

对象始终拥有其原型的内部知识,存储在其[[Prototype]]内部槽中。

__proto__
属性是一种通过代码访问内部已知原型的方法。对象缺少
__proto__
属性不会影响其 [[Prototype]] 插槽,该插槽仍然存在。

说得非常清楚:

coke
有一个原型(存储在[[Prototype]]中),并且该原型就是对象
drink
。您可以通过
Object.getPrototypeOf(coke)
看到这一点。然而,这就是整个原型链,因为
drink
的原型是
null
。因此,
coke
无法从
__proto__
继承
Object.prototype.__proto__
,因为它的原型链中没有
Object.prototype

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.