JavaScript各种继承方式和优缺点

原型链继承

function SuperClass() {  
    this.superValue = true;  
  }  
  //为父类添加公有方法  
  SuperClass.prototype.getSuperValue = function () {  
    return this.superValue;  
  };  
  //声明子类  
  function SubClass() {  
    this.subValue = false;  
  }  
  //继承父类  
  SubClass.prototype = new  SuperClass();//将父类对象赋值给子类原型,子类原型可访问父类原型上的属性和方法--类式继承原理  
  //子类添加公有方法  
  SubClass.prototype.getSubValue = function() {  
    return this.subValue;  
  }; 

缺点:
1、子类通过其原型prototype对父类实例化,继承了父类。但当父类中的共有子类通过其原型prototype对父类实例化,继承了父类。但当父类中的共有属性是引用类型时,会在子类中被所有的实例共用,如此在一个子类实例中更改从父类中继承过来的公有属性时,会影响到其他子类
2、由于子类是通过原型prototype实例化父类实现继承的,所以在创建子类的时候,无法向父类传递参数,

借用构造函数(经典继承)

function SuperClass(id) {  
    this.book = ['javascript','html','css'];//引用类型共有属性  
    this.id = id;//值类型公有属性  
  }  
  //父类声明原型方法  
  SuperClass.prototype.showBooks = function() {  
    console.log(this.books);  
  }  
  //声明子类  
  function SubClass(id) {  
    //继承父类  
    SuperClass.call(this,id);  
  } 

优点:
1、避免了引用类型的属性被所有实例共享
2、可以向父类传参 缺点:
1、父类的原型方法不会被子类继承 2、方法都在构造函数中定义,每次创建实例都会创建一遍方法。

组合式继承

原型链继承和经典继承双剑合璧

function SuperClass(name) {  
    this.name = name;  
    this.book = ['javascript','html','css'];  
}  
SuperClass.prototype.getName = function () {  
    console.log(this.name);  
};  
function SubClass(name,time) {  
    //构造函数式继承,继承父类name属性  
    SuperClass.call(this,name);  
    this.time = time;  
}  
  //类式继承,子类原型继承  
SubClass.prototype = new SuperClass();  
  //子类原型方法  
SubClass.prototype.getTime = function () {  
    console.log(this.time);  
};

优点:
融合原型链继承和构造函数的优点,是 JavaScript 中最常用的继承模式
缺点:
父类的构造函数执行了两遍:一次在子类的构造函数中call方法执行一遍,一次在子类原型实例化父类的时候执行一遍。

原型式继承

类似于Object.create的模拟实现,将传入的值当作创建对象的原型

function createObj(o) {
    function F(){}
    F.prototype = o;
    return new F();
}

ECMAScript5通过新增 Object.create()方法规范了原型式继承 缺点:包含引用类型的属性值始终都会共享相应的值,这点跟原型链继承一样。

寄生组合式继承

借用构造函数 + 原型式继承的结合体;是一种比较常见的成熟的方式

// 原型继承
function inheritPrototype(subType, superType){
  var prototype = Object.create(superType.prototype); // 创建对象
  prototype.constructor = subType;                    // 增强对象
  subType.prototype = prototype;                      // 指定对象
}

// 父类初始化实例属性和原型属性
function SuperClass(name){
  this.name = name;  
   this.book = ['javascript','html','css'];  
}
SuperClass.prototype.getName = function(){
  alert(this.name);
};

// 借用构造函数继承
function SubClass(name, age){
  SuperClass.call(this, name);
  this.time = time;
}

// 将父类原型指向子类
inheritPrototype(SubClass, SuperClass);

// 新增子类原型属性
SubClass.prototype.getTime = function(){
  alert(this.time);
}

var instance1 = new SubClass("js",12);
var instance2 = new SubClass("scss", 12);

es6新增的extends方式

Class 可以通过extends关键字实现继承;他的继承核心和寄生组合式继承很像

class SuperClass {
}

class SubClass extends SuperClass {
  constructor(x, y) {
    super(x, y); // 调用父类的constructor(x, y)
    this.color = color;
  }
}

小红包免费领
小礼物走一走
Last Updated:
Contributors: slbyml
部分内容来源于网络,如有侵权,请留言或联系994917123@qq.com;访问量:waiting;访客数:waiting