js其余继承方式复习整理

64 阅读2分钟

「这是我参与11月更文挑战的第27天,活动详情查看:2021最后一次更文挑战

上篇文章简单说了原型继承、原型链继承,本篇文章将进行下扩展,说下剩余的几种继承方式:

父类属性:

function Animal(name){
  //属性
  this.name  = name
  //实例方法
  this.call=function(call){
    console.log(this.name + 'call'+'叫')
  }
}
//原型方法
Animal.prototype.eat = function(food){
  console.log(this.name + '吃' + food);
}

构造函数继承:

function Cat(name){
  Anminal.call(this); 
  this.name = name;
}
let cat = new Cat();

实现思路:可以用.call()和.apply()将父类构造函数引入子类函数

优点:

1、 解决了子类构造函数向父类构造函数中传递参数问题

2、 可以实现多继承

缺点:

1、因为方法都在构造函数中定义,所以无法实现构造函数复用,每次使用都需要重新调用

2、不能继承原型属性/方法,只能继承父类的实例属性和方法

组合继承:

function Animal(name,call){
  this.name = name 
  this.call = call
}
Animal.prototype.eat = function(){
  return this.name + this.call + '叫'
}

function Cat(name,call){
  Animal.call(this,name,call)
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
let cat = new Cat('咪咪','喵喵');
cat.eat(); 

实现思路:组合原型链继承和构造函数继承方式,调用父类构造函数,继承父类的属性,通过将父类实例作为子类原型,实现函数复用

优点:

1、 可以继承父类原型上的属性,还可以可以继承原型的属性和方法

2、 可以传参,函数可以复用

3、 不存在引用属性问题

缺点:

1、调用了两次父类构造函数,会有两份实例

寄生继承:

function Animal(type){
let obj = Object.create(type);
obj.eat = '鱼';
return obj;
}
var Cat = {
name:'咪咪',
call:'喵喵'
}
let cat = Animal(Cat);

实现思路:寄生是指函数内返回对象然后调用,创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后返回对象

优点:

1、解决了了组合继承中构造函数调用了两次父类构造函数的问题

缺点:

1、没用到原型,无法复用

寄生组合继承:

//父类函数
function Animal(name,call){
  this.name = name
  this.call = call
}
//父类方法
Animal.prototype.eat = function(){
  return this.name + this.call + '叫'
}


//子类
function Cat(name,call){
  //继承父类属性
  Animal.call(this,name,call)
}
//继承父类方法
(function(){
  let Dog = function(){};
  Dog.prototype = Animal.prototype;
  //父类的实例作为子类的原型
  Cat.prototype = new Dog();
})();
//修复构造函数指向问题
Cat.prototype.constructor = Cat;
let cat = new Cat();

实现思路:寄生是指函数内返回对象然后调用,组合是在函数中用apply或者call方法引入另一个构造函数,可传参,函数的原型等于另一个实例。寄生组合是通过寄生的方式来修复组合式继承的不足

优点:

具备组合继承的一些优点,同时修复了组合继承调用了两次父类构造函数,会有两份实例的问题