JS红宝书第八章 读书笔记

90 阅读2分钟

什么是原型

首先先理解构造函数的概念,我们可以通过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 = 子类构造函数 ;
}