js常见的6种继承方式

一、原型继承
  //父类型
  function Person() {}
  Person.prototype.setAge = function () {}
  //子类型
  function Student() {}
  // 子类型的原型为父类型的一个实例对象
  Student.prototype = new Person()  //核心代码
  优点:
    1.父类新增原型方法/原型属性,子类都能访问到
    2.简单,易于实现
  缺点:
    1.无法实现多继承
    2.来自原型对象的所有属性被所有实例共享
    3.创建子类实例时,无法向父类构造函数传参
    4.要想为子类新增属性和方法,必须要在Student.prototype = new Person() 之后执行,不能放到构造器中

二、借用构造函数继承
  function Person(name, age) {}
  Person.prototype.setAge = function () {}
  function Student(name, age, price) {
    Person.call(this, name, age)  //核心代码,相当于: this.Person(name, age)
  }
  优点:
    1.解决了原型链继承中子类实例共享父类引用属性的问题
    2.创建子类实例时,可以向父类传递参数
    3.可以实现多继承(call多个父类对象)
  缺点:
    1.实例并不是父类的实例,只是子类的实例
    2.只能继承父类的实例属性和方法,不能继承原型属性和方法
    3.无法实现函数复用,每个子类都有父类实例函数的副本,影响性能

三、原型链+借用构造函数的组合继承
  function Person (name, age) {}
  Person.prototype.setAge = function () {}
  function Student (name, age, price) {
    Person.call(this, name, age)
  }
  Student.prototype = new Person() //核心代码
  //组合继承也是需要修复构造函数指向的
  Student.prototype.constructor = Student //核心代码
  优点:
    1.可以继承实例属性/方法,也可以继承原型属性/方法
    2.不存在引用属性共享问题
    3.可传参
    4.函数可复用
  缺点:
    1.调用了两次父类构造函数,生成了两份实例  

四、组合继承优化1
  function Person (name, age) {}
  Person.prototype.setAge = function () {}
  function Student (name, age, price) {
    Person.call(this, name, age)  //核心代码
  }
  Student.prototype = Person.prototype  //优化关键
  优点:
    1.不会初始化两次实例方法/属性,避免的组合继承的缺点
  缺点:
    1.没办法辨别是实例是子类还是父类创造的,子类和父类的构造函数指向是同一个。  

五、组合继承优化2(ES5最完美的继承方法)
  function Person (name, age) {}
  Person.prototype.setAge = function () {}
  function Student (name, age, price) {
    Person.call(this, name, age)  //核心代码
  }
  Student.prototype = Object.create(Person.prototype) //核心代码
  Student.prototype.constructor = Student //核心代码

六、ES6中class 的继承
  //定义一个父类
  class Person {
    //调用类的构造方法
    constructor(name, age) {
      this.name = name
      this.age = age
    }
  }
  //定义一个子类
  class Student extends Person {
    constructor(name, age, salary) {
      super(name, age)  //核心代码,调用父类的constructor(name, age)
      this.salary = salary
    }
  }
  优点:
    1.语法简单易懂,操作更方便
  缺点:
    1.并不是所有的浏览器都支持class关键字

搬运自:https://github.com/ljianshu/Blog/issues/20

posted on 2019-09-10 10:55  肥嘟嘟啊左卫门  阅读(249)  评论(0编辑  收藏  举报