为什么[[Prototype]]多套了一层

101 阅读1分钟

说实话,很久没有关注原型这个问题了,我对浏览器的__proto__输出还停留在这个印象

image.png

直到有一天,输出对象的时候,开始看新的[[Prototype]]的时候,发现了一个问题,为什么[[Prototype]]多套了一层:

image.png

思考

先简单回顾一下原型

  1. 构造函数new调用的时候,prototype属性会变成对象原型,也就是说
function a(){}

let b = new a()

Object.getPrototypeOf(b) === a.prototype // true
  1. 访问对象的原型标准方式是使用Object.getPrototypeOf,当然还有一种非标准的访问方式,使用__proto__
  2. 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

image.png