为什么__proto__未定义?

时间:2016-02-17 13:34:24

标签: javascript prototype v8

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

1 个答案:

答案 0 :(得分:7)

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

  

这是按照指定的方式工作。 ES6 __proto__是在Object.prototype上定义的getter。对于在其原型链中没有该对象的对象,它是不可访问的(就像,例如,hasOwnProperty不是)。您需要使用Object.getPrototypeOf。

确实如此: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无法从__proto__继承Object.prototype.__proto__,因为其原型链中没有Object.prototype