原型链是什么
先说一下原型是什么,举例说明
假设有一个普通对象x={},这个x会有一个隐藏属性,叫做__ ?????__ ,这个属性会指向Object.prototype,即
x.__ ?????__ === Object.prototype // 原型
- 所以,x的原型是
Object.prototype,或者说Object.prototype是x的原型 - 而这个????? 属性唯一作用就是用来指向x的原型的
- 如果没有????? 属性,x就不知道自己的原型是谁了
接下来说一下原型链是什么,举例说明
假设有一个数组对象a=[],这个a也会有一个隐藏属性,叫做__ ?????__ ,这个属性会指向 Array.prototype,即
a.__ ?????__ === Array.prototype
此时,a的原型是Array.prototype,跟上面的x一样。但也有一点不一样,那就是Array.prototype也有一个隐藏属性????? ,指向Object.prototype,即
// 用x表示 Array.prototype
x.__ ?????__ === Object.prototype
这样一来,a就有两层原型:
- a的原型是Array.prototype
- a的原型的原型是Object.prototype
于是就通过隐藏属性 __ ?????__ 形成了一个链条:
a ===> Array.prototype ===> Object.prototype
这就是原型链。
怎么做: 看起来只要改写x的隐藏属性 __ ????? __ 就可以改变x的原型(链)
x.__?????_ = 原型
但是这不是标准推荐的写法,为了设置x.__ ?????__ , 推荐的写法是
const x = Object.create(原型)
// 或
const x = new 构造函数() // 会导致 x.__?????__ === 构造函数.prototype
解决了什么问题: 在没有Class的情况下实现继承。以 a ===> Array.prototype ===> Object.prototype 为例,我们说:
- a是Array的实例,a拥有Array.prototype里的属性
- Array继承了Object
- a是Object的间接实例,a拥有Object.prototype里的属性 这样一来,a 就既拥有 Array.prototype 里的属性,又拥有 Object.prototype 里的属性。
优点:简单
缺点:跟class相比,不支持私有属性
怎么解决缺点:使用class