总览
一、借助构造函数
1 | function Parent1() { |
缺点
子类没有继承父类的原型方法 只继承了父类构造函数中的属性和方法
1 | Parent1.prototype.method = (arg) =console.log(arg); |
二、借助原型链
1 | function Parent2() { |
原型图如下
缺点
引用类型的属性被所有实例共享,实例之间会互相影响
1 | let c21 = new Child2(); |
三、组合(构造+原型链)
1 | function Parent3() { |
优点
每个实例不会再互相影响
缺点
实例化时,父类被构造了两次,这没有必要 call一次,new一次
四、组合优化一
1 | function Parent4() { |
缺点
无法判断实例的构造函数是父类还是子类
1 | let c41 = new Child4(); |
但其实,构造函数就是父类本身
1 | console.log(c41.constructor); // Parent4 |
很难得才通过Parent4.call(this)
改变了构造函数的指向,现在又改回去了?天……不想看下去了行不行,兄dei,坚持一会就是胜利,别打瞌睡
Child4.prototype = Parent4.prototype
只是把Child4
的prototype
属性指针指向了Parent4.prototype
这个引用对象而已,实际上Parent4.prototype.constructor = Parent4
五、组合优化二
1 | function Parent5() { |
但是,这时候,实例对象的constructor
依然是Parent5
所以需要重新指定实例对象的构造器
1 | Child5.prototype.constructor = Child5; |
1 | let c51 = new Child5(); |