JavaScript各种继承方式(三):组合继承(combination inheritance)

 

一 原理

 

组合继承仅仅是同时使用了原型链继承和构造函数继承。

具体做法是,将父类的实例作为子类的构造函数的原型对象,并在子类的构造函数中调用父类的构造函数。

 

function Fruit(name){
    this.name = name;
    this.nutrition = ['维生素'];
}

Fruit.prototype.eat = function(){
    console.log('eat');
}

function Mango(name,level){
    Fruit.call(this,name); // 第二次调用父类的构造函数
    this.level = level;
}

let fruit = new Fruit(); // 第一次调用父类的构造函数
Mango.prototype = fruit;
Mango.prototype.constructor = Mango;

let mango1 = new Mango('泰国芒果','优');
let mango2 = new Mango('海南芒果','良');

// 子类的实例持有两份继承的属性:一份是共享原型对象中的属性;另一份是自己的私有属性。
mango1.nutrition.push('膳食纤维');
mango2.nutrition.push('柠檬酸');
console.log(mango1.nutrition,mango1.__proto__.nutrition); // ["维生素", "膳食纤维"] ["维生素"]
console.log(mango2.nutrition,mango2.__proto__.nutrition); // ["维生素", "柠檬酸"] ["维生素"]
console.log(mango1.__proto__.nutrition === mango2.__proto__.nutrition); // true

// 拼接了原型链,支持instanceof、isPrototypeOf
console.log(mango1 instanceof Fruit); // true
console.log(mango1 instanceof Mango); // true
console.log(Fruit.prototype.isPrototypeOf(mango1)); // true
console.log(fruit.isPrototypeOf(mango1)); // true

 

二 优点

 

1 既可以从父类的构造函数的原型对象继承方法,也能从父类的构造函数继承属性。

2 既是父类的实例,也是子类的实例。

3 拼接了原型链,支持instanceof、isPrototypeOf检测。

4 调用父类的构造函数时可以传参数。

5 从父类的构造函数的原型对象继承的方法,可以被复用,被所有子类的实例共享。

 

三 缺点

 

父类的构造函数执行了两次,从而父类的实例属性被创建了两次,在子类的原型对象、子类的实例中都存在。父类的实例属性被继承了两次,子类的实例中的属性覆盖了子类的原型对象中的属性。浪费了内存和性能。

 

posted on 2018-12-28 15:10  沙滩海风  阅读(425)  评论(0编辑  收藏  举报

导航