JavaScript 的几种继承方式?

  • 原型链继承
  • 构造函数继承
  • 组合继承 (伪经典继承)
  • 原型式继承
  • 寄生式继承
  • 寄生组合式继承
  • ES6 extend 继承

1, 原型链继承

原理是将父对象的属性和方法通过prototype进行引用

function people() {
    this.flag = true;
    this.func = function() {
        console.log("this is people func");
    }
}
function boy() {
    this.sex = "boy";
}
boy.prototype = new people();
var peo1 = new boy();
console.log( peo1.flag );     // true
console.log( peo1.func() );   // this is people func
console.log( peo1.sex );      // boy

缺点:

  • 实例对象的属性被共享
  • 无法向父对象的方法传递参数

2, 构造函数继承

构造函数继承主要在继承对象中使用 call()、apply() 完成。

function people(name) {
    this.name = name || "xiaoming";
}

// 对people进行继承
function boy() {
    people.call(this, "wangming");
    this.age = 18;
}
var peo1 = new boy();
console.log( peo1.name ); //wangming
console.log( peo1.age ); //18

缺点:

  • 函数无法复用
  • 父对象的方法对子类不可见

3, 组合继承 (伪经典继承)

结合原型链和构造函数继承。思路是利用原型链继承原型上的属性和方法,构造函数继承实例的属性,也就是父对象自己的属性。

function people(name) {
    this.name = name || "xiaoming";
}
people.prototype.sayName = function() {
    alert(this.name);
}

//构造函数继承属性
function boy(name, age) {
    people.call(this, name);
    
    this.age = age || 18;
}
//原型链继承方法
boy.prototype = new people();
boy.prototype.sayAge = function() {
    alert(this.age);
}

var peo1 = new boy("zhangsan", 22);
peo1.sayName();  // zhangsan
peo1.sayAge();   // 22

因为结合了原型链和构造函数继承的优点,成为了最常用的继承模式。但也有缺点,就是调用了两次父对象的构造函数。(使用call时一次,使用new又是一次)

4,原型式继承

这种继承模式的思路是创建一个基本对象,里面包含通用的属性、函数。通过特定函数创建实例。

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

利用该函数创建的实例对象其实是原来基本对象的副本。ES5中新增了Object.create()对其进行规范。兼容IE9+。

var person = {
    name: "Neo",
    sayName: function() {
        console.log(this.name);
    }
}
var obj = Object.create(person);
obj.name = "test";
obj.sayName();    // test
person.sayName(); // Neo

5,寄生式继承

寄生式与原型式相关。用一个函数封装继承过程,类似于工厂模式。

function createAnother( obj ) {
    var clone = Object.create(obj);
    clone.sayName = function() {
        alert(this.name);
    }
    return clone;
}
var people = {
    name: "test"
}
var boy = createAnother(people);
boy.sayName(); // test

6,寄生组合式继承

寄生式继承与组合式继承,实现一种最理想的继承模式。

function inheritPrototype( subItem, superItem ) {
    var clone = Object.create(superItem.prototype);
    clone.constructor = subItem;
    subItem.prototype = clone;
}
function superItem(name) {
    this.name = name;
}
superItem.prototype.sayName = function() {
    alert(this.name);
}

function subItem(name, age) {
    superItem.call(this, name);
    this.age = age || 18;
}
inheritPrototype(subItem, superItem);

var obj = new subItem("leo");
obj.sayName();    //leo

7, ES6 extend 继承

利用ES6提供的类继承关键字extends实现。

class People {
    constructor(){
        this.name = "leo";
    }
    sayName(){
        alert(this.name);
    }
}
class Boy extends People{
    constructor(props){
        super(props);
        this.name = "li"
    }
}
var peo1 = new People();
var peo2 = new Boy();

peo1.sayName(); // leo
peo2.sayName(); // li

以上就是我所总结的7中继承方式