为什么 __proto__ 未定义?

Why is __proto__ undefined?

在阅读 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

我曾经opened an issue for this behavior,但它作为符合标准的行为被关闭了。根据问题关闭原因:

This is working as specified. ES6 __proto__ is a getter defined on Object.prototype. For an object that doesn't have that in its prototype chain it is not accessible (just like, say, hasOwnProperty isn't). You need to use Object.getPrototypeOf instead.

确实如此:ES6 section B.2.2.1定义了Object.prototype.__proto__;因此,__proto__ 属性 继承自 Object.prototype。但是,您的 coke 对象是使用 Object.create(null) 创建的,因此它的原型链中没有 Object.prototype

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

完全清楚:coke 是否有原型(存储在 [[Prototype]] 中),并且该原型是对象 drink .你可以用 Object.getPrototypeOf(coke) 看到这个。然而,那是整个原型链,因为drink的原型是null。因此,coke 无法从 Object.prototype.__proto__ 继承 __proto__,因为它的原型链中没有 Object.prototype