原型链继承
1 | function Zoo() { |
缺点: 不能向父类构造函数(Zoo)传递参数
构造函数继承
——在子类型构造函数的内部调用父类构造函数,使用 apply()和 call()方法将 this 指向子类
1 | function Zoo(zoo) { |
缺点: 无法调用父类原型上的方法 例如:
1 | Zoo.prototype.sleep = function () { |
组合继承
——将原型链继承和构造函数继承组合到一起。使用原型链继承实现对原型属性和方法的继承,用借用构造函数继承实现对父实例属性的继承。这样既通过在原型上定义方法实现了函数复用,又能保证每个实例都有自己的属性
1 | function Zoo(zoo) { |
缺点: 会调用两次超类型构造函数,一次是在创建子类型原型的时候,一次是在子类型构造函数的内部,占用内存。
寄生组合式继承
——寄生组合式继承是对组合继承的进一步优化。我们先看一下为什么要写这个语句。
1 | panda.prototype = new Zoo(); |
我们无非是想让 panda 继承 Zoo 的原型。但是我们为什么不直接写成这样呢?
1 | panda.prototype = Zoo.prototype; |
——这样写确实可以实现子类对象对父类对象原型的继承。但是这样写的话:所有继承该父类的子类对象的原型都指向同一个了。也就是说 SubType 不能有自己的原型了。这显然不是我们想要的。
——既然不能直接继承,那可不可以间接继承 Zoo.prototype 呢。这就是最终的解决方案:间接组合式继承。
——我们让一个对象去指向 Zoo.prototype,然后让 panda.prototype 指向这个函数产生的对象不就可以了嘛。
——核心函数:
1 | function indirect(son, father) { |
优点: 只调用了一次 Zoo 构造函数,因此避免在 panda.prototype 上创建不必要的,多余的属性,与此同时,原型链还能保持不变,还能正常使用 instanceof 和 isPrototypeOf(),因此,寄生组合式继承被认为是引用类型最理想的继承范式。
ES6 继承
1 | class Zoo { |
——Class 可以通过 extends 关键字实现继承
——子类必须在 constructor 方法中调用 super 方法,否则新建实例时会报错。
——这是因为子类自己的 this 对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用 super 方法,子类就得不到 this 对象。
—— super(zoo)里的参数 zoo 是父亲的属性 要是用父类属性需要加上参数
- Post link: https://blog.gaocaipeng.com/2019/02/10/cfddix/
- Copyright Notice: All articles in this blog are licensed under unless otherwise stated.