说实话,很久没有关注原型这个问题了,我对浏览器的__proto__输出还停留在这个印象
直到有一天,输出对象的时候,开始看新的[[Prototype]]的时候,发现了一个问题,为什么[[Prototype]]多套了一层:
思考
先简单回顾一下原型:
构造函数被new调用的时候,prototype属性会变成对象的原型,也就是说
function a(){}
let b = new a()
Object.getPrototypeOf(b) === a.prototype // true
- 访问对象的
原型的标准方式是使用Object.getPrototypeOf,当然还有一种非标准的访问方式,使用__proto__ ES6增加了[[Prototype]]内部属性来指向原型,当然__proto__现在为止还可以使用
其实一开始我把__proto__和[[Prototype]]看成是一样的,所以怎么也想不通,直到我想到实现这两个字,才反应过来,[[Prototype]]确实是标准,但是__proto__不是浏览器的自我实现么,所以说,[[Prototype]]上实现了__proto__。按照这种思路,我们再来看这多套一层就非常的合理。首先是按照__proto__的方式访问,那就是这样:
let a = {}
a.__proto__.__proto__ === null // true
意思就是先访问[[Prototype]]上的__proto__,当然此时已经是Object.prototype了,所以访问Object.prototype.__proto__就是null,这很符合原型的设计,顶层为null
再按照[[Prototype]]这个属性来访问原型:
let a = {}
Object.getPrototypeOf(Object.getPrototypeOf(a)) === null //true
a对象的原型是Object.prototype,但是Object.prototype的[[Prototype]]是不存在的,所以返回null