尽人皆知,JavaScript 的继续是完成继续,而没有 Java 中的接口继续。这是因为 JavaScript 中函数没有署名,而完成继续依托的是原型链来完成的。
原型链继续
JavaScript 中经由过程修正对象原型指向的对象来完成继续,等于将一个对象的原型指向要继续的对象实例,从而完成继续对象的属性及要领。
function SuperType() {
this.type = 'super';
}
SuperType.prototype.getType() {
return this.type;
}
function SubType() {
this.type = 'sub';
}
SubType.prototype = new SuperType();
var sub = new SubType();
console.log(sub.getType()); // "sub"
原型链继续的不足
实际上,上面的代码还缺乏一句代码,我们将 SubType 的原型指向了 SuperType 的实例,即SubType.prototype.constructor
会返回 SuperType
而不是 SubType
,运用 instanceof
操作符返回的将是 SuperType
。所以需要将 SubType.prototype.constructor
从新指向 SubType
。
// ...
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
// ...
但即使是如许,原型链继续依旧有两点题目:原型中的实例援用范例属性会在一切对象实例中同享,没法想 Java 的继续一样向父类的组织函数中通报参数。
其他继续体式格局
因为原型链继续存在一些不足,为了处理这些不足,JavaScript 中另有其他的几种继续的体式格局。
借用组织函数
因为原型链没法通报参数到父类的组织函数中,因而涌现了这类叫做借用组织函数的手艺。望文生义,等于借用父类的组织函数在子类中举行挪用。
function SuperType() {
// ...
}
function SubType() {
SuperType.call(this); // <- 实行父类组织函数
// ...
}
借用组织函数虽然处理了组织函数传参的题目,然则当父类具有要领时每一个子类的实例都邑具有自力的要领,这个题目与零丁运用组织函数形式定义范例的时刻雷同。
组合继续
类比运用组织函数形式定义范例时的处理要领(组合组织函数形式与原型形式),继续时的处理要领也相似。即组合原型链继续和借用组织函数,属性由借用组织函数的体式格局继续,要领由原型链继续。
实际上也就是在原型链继续的代码中添加在子类的组织函数中挪用父类组织函数。
function SuperType() {
this.type = 'super';
}
SuperType.prototype.getType() {
return this.type;
}
function SubType() {
SuperType.call(this);
this.type = 'sub';
}
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
寄生组合式继续
组合继续是经常使用的继续体式格局,然则一样的也是有不足之处:挪用了两次父类的组织函数,一次在子类组织函数中挪用父类组织函数,一次在实例父类对象赋值给子类的原型。
寄生组合式继续在指定子类的原型的时刻没必要挪用父类的组织函数,而是直接运用 Object.create()
建立父类原型的副本。
function SuperType() {
// ...
}
function SubType() {
SuperType.call(this);
// ...
}
SubType.prototype = Object.create(SuperType.prototype); // 直接运用父类原型建立副本
SubType.prototype.constructor = SubType;
ES6 中的继续
ES6 引入了 class
关键子,可以像其他言语中一样运用 extends
关键字来继续。虽然可以运用 extends
完成继续,但实际上内部照样基于原型。
class SubType extends SuperType {
constructor() {
super();
// ...
}
// ...
}