JavaScript继承
JavaScript继承
谈OOP怎么可能不提继承呢😄!在原型链中,已经介绍,OOP语言支持两种继承方式:接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际的方法。 在 ECMAScript 中无法实现接口继承。ECMAScript 只支持实现继承,而且其实现继承主要是依靠原型链 来实现的。
《JavaScript高级程序设计(4th)》中介绍了介绍原型链、构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合式继承等6种方法。
但是通过细心研读可以发现,书中真正推荐使用继承方法只有两个:组合继承(combination inheritance)或寄生组合式继承,以及class关键字
(寄生)组合继承
组合继承(combination inheritance)又称伪经典继承(pseudo classical inheritance),它使用原型链实现对原型属性和方法的继承,而通过构造函数实现对实例属性的继承。
1 | |
- 共用方法写在
Parent.prototype中,通过原型链实现继承 - 非共用属性(
name1)放在构造函数中,让每一个实例都有自己的副本 - 组合继承方式调用了两次构造函数,一次是创建子类
Child的原型prototype时,一次是在子类的构造函数中借用构造函数时。这样可能得到一些没用的实例属性,同时复杂的构造函数可能会影像性能。
为了优化这个过程,就出现了寄生组合继承模式:把new关键字换成 Object.create() 方法即可
1 | |
基于 class 关键字继承
1 | |
派生类的方法可以通过 super 关键字引用它们的原型。这个关键字只能在派生类中使用,而且仅
限于类构造函数、实例方法和静态方法内部。在类构造函数中使用 super 可以调用父类构造函数。
不能在调用 super 之前使用this,否则会抛出 ReferenceError
总结:重要继承模式
- 原型链继承 : 得到方法
1
2
3
4
5
6function Parent(){};
Parent.prototype.test = function(){};
function Child(){};
Child.prototype = new Parent(); // 子类型的原型指向父类型实例
Child.prototype.constructor = Child
var child = new Child(); //有test() - 借用构造函数 : inherit instance properties
1
2
3
4
5
6function Parent(xxx){this.xxx = xxx}
Parent.prototype.test = function(){};
function Child(xxx,yyy){
Parent.call(this, xxx);//借用构造函数 this.Parent(xxx)
}
var child = new Child('a', 'b'); //child.xxx为'a', 但child没有test() - 组合
1
2
3
4
5
6
7function Parent(xxx){this.xxx = xxx}
Parent.prototype.test = function(){};
function Child(xxx,yyy){
Parent.call(this, xxx);//借用构造函数 this.Parent(xxx)
}
Child.prototype = new Parent(); //得到test()
var child = new Child(); //child.xxx为'a', 也有test()
原型式继承—— Object.create() - JavaScript | MDN (mozilla.org)](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create)) 的内部逻辑
1
2
3
4
5function object(o) {
function F() {}
F.prototype = o;
return new F();
}
版权声明:本文作者为「Andy8421」.本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!