JavaScript之构造函数继承和组合继承的优缺点

一.构造函数继承

  1. 构造函数继承的基本思路是在子类型的构造函数中,调用要继承的构造函数,具体实现如下:
function Parent() {
  this.name = ["heyushuo", "kebi"];
}

function Child() {
  Parent.call(this);
  // 或者 Parent.apply(this);
}

var Person1 = new Child();
Person1.name.push("kuli");
console.log(Person1.name); //["heyushuo", "kebi","kuli"];
var Person2 = new Child();
console.log(Person2.name); //["heyushuo", "kebi"];
// 通过上边的两个打印,Child的两个实例继承的name属性不会互相影响
// 因为,创建Child实例的环境下调用Parent构造函数,这样可以使得每个实例都会具有自己的name属性,所以两个不会互相影响

2. 优点(可以传递参数)

function Parent(name) {
  this.name = name;
}

function Child() {
  Parent.call(this, "heyushuo");
  //或者Parent.apply(this, ["heyushuo"]);
}
var Person = new Child();
console.log(Person.name); //heyushuo

// 需要注意的:为了确保Parent构造函数不会重写子类型的属性,需要在Parent.call(this)之后在定义子类型中的属性

3.构造函数的缺点

因为方法和属性只能写在构造函数中,因此不能实现函数复用 只能继承父类的实例属性和方法,不能继承原型属性/方法 (原型中定义的方法和属性对于子类是不可见的)

二.组合继承(原型链和构造函数组合式继承)

通俗来讲就是用原型链实现对原型属性和方法的继承,用借用构造函数继承来实现对实例属性的继承。

function Parent(name) {
  this.name = name;
  this.newArr = ["red", "blue", "green"];
}
Parent.prototype.sayName = function() {
  console.log(this.name);
};

function Child(name) {
  Parent.call(this, name);
  this.age = 26;
}

Child.prototype = new Parent();
//重写Child.prototype的constructor属性,使其执行自己的构造函数Child
Child.prototype.constructor = Child;
Child.prototype.sayAge = function() {
  console.log(this.age);
};

var Person1 = new Child("heyushuo");
console.log(Person1);
Person1.newArr.push("yellow");
console.log(Person.newArr); //["red", "blue", "green","yellow"]
Person.sayName(); //heyushuo

var Person2 = new Child("kebi");
console.log(Person2.newArr); //["red", "blue", "green"]
Person.sayName(); //kebi

通过一张图来看一下:

总结

  1. 组合式继承避免了原型链和构造函数的缺陷,融合了他们的有点,成为最常用的继承模式
  2. 组合式继承有一个缺点, 如上图可以看出, 创建的实例和原型上存在两份相同的属性即(name 和 newArr);
原文地址:https://www.cnblogs.com/heyushuo/p/10004699.html