原型链概念很多,在这里举例说明一下
假设我们有一个普通对象x={},那么这个x就有一个隐藏属性,叫__proto__,这个隐藏属性指向Object.prototype,即
x.__proto__ === Object.prototype
此时我们说x的原型就是Object.prototype,或者Object.prototype就是x的原型
而__proto__作用就是指向x的原型
接下来说一下原型链
假设我们有一个数组对象a=[],那么a也有一个隐藏属性叫__proto__,这个属性指向Array.prototype,即
a.__proto__ === Array.prototype
此时,我们说 a 的原型是 Array.prototype,跟上面的 x 一样。但又有一点不一样,那就是Array.prototype也有一个隐藏属性,即
// b代表Array.prototype
b.__proto__ === Object.prototype
这样一来,a就有了两层原型
- a的原型是Array.prototype
- a的原型的原型是Object.prototype
于是通过__proto__隐藏属性形成了一条链条,这就是原型链
修改原型链
看起来只要改写 x 的隐藏属性 __?????__ 就可以改变 x 的原型(链)
x.__proto__ = 原型
但是这样写是不推荐的,正确的写法应该
const x = Object.create(原型)
//或者
const x = new Fn() //Fn为构造函数 x.__proto__ === Fn.prototype
原型链解决了什么
在没有class的情况下实现了继承,以a=>Array.prototype=>Object.prototype为例
- a是Array的实例,a 拥有 Array.prototype 里的属性
- Array 继承了 Object
- a 是 Object 的间接实例,a 拥有 Object.prototype 里的属性
这样一来,a 就既拥有 Array.prototype 里的属性,又拥有 Object.prototype 里的属性
tip: 不支持私有属性
可以使用ES6的class
也可以使用__scope__: 'xxx' (约定俗成)