继承的几种方式

120 阅读2分钟
  1. 原型链继承

 代码:  function Person(name, age) {

  this.name = name
  this.age = age
}

Person.prototype.say = function() {
  console.log('说话了')
}

const p1 = new Person('张三', 19)

 - 是利用了原型链的指向方法来实现的,把子级实例对象指向父级的构造函数的prototype方法 从而可以利用__proto__来指向父级的prototype的方法,从而达到继承的目的

— 缺点:这个方法只能够继承父级的方法,不能继承父级的属性,而且父原型和子原型公用同一个原型


2. 借用构造函数继承

- 把父亲的构造函数调用到子构造函数
利用call的方法改变this指向,让父类构造函数的属性指向子类构造函数,子类就可以通过实例对象来调用父类的属性从而实现继承
- 但是只能够继承父类的属性,不能继承父类的方法


3. 组合式继承

是原型链继承和借用构造函数继承的混合方法,,**组合继承是JavaScript最常用的继承方式**;不过,它也有自己的不足。**组合继承最大的问题**就是**无论什么情况下,都会调用两次超类型构造函数**:一次是在把父级构造函数指向子级原型对象的时候,一次是在子级构造函数中用call改变this指向的时候call会自动调用一次。



4.寄生组合继承

这个inheritPrototype()函数接收两个参数:子类构造函数和父类构造函数。在这个函数内部,第一步是创建父类原型的一个副本。然后,给返回的prototype对象设置constructor属性,解决由于重写原型导致子类原型对象中的默认constructor属性丢失的问题。最后将新创建的对象prototype赋值给子类原型。
function inheritPrototype (subType, superType) {
    let prototype = Object(superType.prototype); // 创建父类原型的一个副本
    prototype.constructor = subType; // 给返回的对象设置constructor属性
    subType.prototype = prototype; // 将返回的新对象赋值给子类原型
}

总结:
    寄生组合式继承的高效体现在它只调用了一次父类构造函数,并且因此避免了在子类原型上面创建不必要的、多余属性。与此同时,还能保持不变;因此,还能正常使用instanceof

5. es6 类继承

- 由于之前的继承方法太过于复杂,es6新出了一个extends方法,使继承更加简单