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