什么是原型
首先先理解构造函数的概念,我们可以通过new关键字生成对应的实例。 执行new关键字背后运行的机制有:
1、开辟一块内存空间存放内存
2、this指向当前对象实例
3、当前对象实例的原型=构造函数的原型对象
构造函数的痛点
当构造函数中有某方法时(函数),每当我们生成一个实例时都会为这个方法开辟一个函数作用域,造成资源浪费。
引入原型
我们一般将需要共享的数据和方法存放在原型中,这样我们所有通过new 关键字生成的实例都可以共享这些属性和方法,这样就不需要额外开辟内存空间了
JS的继承是基于原型链
1、原型链的问题
子类.prototype = new 父类构造函数()
这样就使得子类成功继承父类的属性和方法
痛点:父类构造函数中会定义属性,本来应该是实例属性,一旦生成继承关系,父类实例的属性就变成子类原型的属性,独立的属性变成共享的。
2、盗用构造函数
子类.constructor({
子类.call(this)
)
子类构造函数内部通过call或apply调用父类构造函数,使得调用子类构造函数生成的子类对象能有独立的属性
痛点:子类不能使用父类的方法,函数不能复用,需要自己定义
3、组合继承
原型链+盗用构造函数
4、原型式继承
let obj = Object.create(targetObj)
obj.proto===targetObj //true
不需要单独创建构造函数就能实现对象间共享信息
5、寄生式继承
和原型式继承很像
function 寄生(targetObject){
let clone = Object.create(targetObject);
clone.add(){}
return clone;
}
创建一个对象,形成继承,加强对象,返回对象
6、寄生式组合继承
组合继承的痛点:需要执行两次父类构造函数
——1、子类.prototype === new 父类.构造函数()
——2、在子类的构造函数中调用 父类.call(this)
我们可以利用寄生式继承替代原型链,从而少调用一次父类构造函数
寄生(子类,父类){
let prototype = Object.create(父类.prototype);
子类.prototype = prototype;
prototype.constructor = 子类构造函数 ;
}