原生javascript中的继承,是考验对JS掌握程度一个重要反馈,现在来总结JavaScript中的几种继承方式,并分析其利弊。主要有三种方式:构造函数方式、原型链继承方式、组合继承以及寄生组合继承方式。
一、借用构造函数
function SuperType(name){
this.colors= ['red','blue','green'];
}
function SubType() {
SuperType.call(this); //利用call调用SuperType的构造函数继承
}
var instancell = new SubType();
instancell.colors.push('black');
console.log(instancell.colors);//'red','blue','green',black
缺点:
1、方法都在构造函数中定义,不能服用。
2、超类型的原型中定义的方法不能继承,不能继承原型。
二、借用原型链继承
function SuperType(){
this.name = "parent2";
this.play = [1,2,3];
}
function SubType(){
this.type = "child2";
}
SubType.prototype = new SuperType();
或者使用Object.create()方法,代码如下:
function SuperType(){
this.name = "parent2";
this.play = [1,2,3];
}
function SubType(){
this.type = "child2";
}
SubType.prototype = Object.create(SuperType);
缺点:原型属性是共享的,修改一个影响全部。
三、组合继承
function SuperType(name){
this.name =name;
this.colors= ['red','blue','green'];
}
SuperTyper.prototype.sayName = function() {
alert(name)
};
function SubType(name, age) {
//继承属性
SuperTyper.call(this, name); //第一次SubTyper调用构造函数
this.age = age;
}
//继承方法
SubTyper.prototype = new SuperTyper(); //第二次调用SuperTyper构造函数
//或 SubTyper.prototype = Object.create(SuperTyper);
SubTyper.prototype.constructor = SubTyper;
SubTyper.prototype.sayAge = function() {
alert(this.age);
}
思路:使用原型链实现对原型属性和方法的继承,借用构造函数来实现对实例属性的继承。
四、寄生组合继承
组合继承存在调用俩次超类型构造函数问题。
...
function SuperType(name){
...
}
function SubType(name, age) {
//继承属性
SuperTyper.call(this, name); //第一次SubTyper调用构造函数
this.age = age;
}
//调用关键继承方法
inheritPrototype(SubType, SuperType);
SubTyper.prototype.sayAge = function() {
...
}
function inheritPrototype(subType, superType) {
var prototype = Object(superType.prototype);
prototype.constructor = subType;
subType.prototype = prototype;
}
优点:寄生组合继承只调用了一次SuperType构造函数,同时保持原型链保持不变。
参考资料:
Object.create() - JavaScript | MDN
如有错误,欢迎指正。