js继承

116 阅读2分钟

js 里的原型继承模型

JavaScript 是基于原型实现面向对象的,那么在JS中,面向对象概念中的继承自然也是基于原型。
js本质上没有类,即使是ES6里面的class,也只是语法糖,实际上是函数,class实现的继承最终转为ES5还是基于原型实现继承。
函数才是js里的一等公民。

寄生组合式继承

网上对js继承有很多方案,社区经过这么多年的发展也衍生出很多方案。但最终形成的继承方案可以描述为: 寄生组合式继承

代码实现

function createObject(o) {
  function Fn() {}
  Fn.prototype = o
  return new Fn()
}
//核心函数(组合函数)
function inheritPrototype(SubType, SuperType) {
  //createObject方法作用:创建一个新对象,将新对象的原型指向父类的原型对象
  // SubType.prototype = Objec.create(SuperType.prototype)
  //将子类的原型指向新创建的对象的原型对象
  SubType.prototype = createObject(SuperType.prototype)
  //给新创建的对象添加一个constructor属性,指向子类
  Object.defineProperty(SubType.prototype, "constructor", {
    enumerable: false,
    configurable: true,
    writable: true,
    value: SubType
  })
}

//定义一个Person类
function Person(name, age) {
  this.name = name
  this.age = age
}

Person.prototype.eating = function() {
  console.log(this.name  + " is eating")
}

//定义一个Student类
function Student(name, age, sno, score) {
  //借用父类函数,将父类的属性保存到子类对象。(可以理解为寄生)
  Person.call(this, name, age)
  this.sno = sno
  this.score = score
}

//调用函数Student类继承Person类
inheritPrototype(Student, Person)

Student.prototype.studying = function() {
  console.log(this.name + " is studying")
}
//测试
var stu = new Student("jack", 18, 9523, 150)
console.log(stu) //Student { name: 'jack', age: 18, sno: 9523, score: 150 }
stu.studying() //jack is studying
stu.eating()   //jack is eating

ES6的class实现继承

class Person {
  constructor(name, age) {
    this.name = name
    this.age = age
  }
  eating() {
    console.log(this.name + " is eating")
  }
  static staticMethod() {
    console.log("PersonStaticMethod")
  }
}

class Student extends Person {
  constructor(name, age, sno) {
    super(name, age)
    this.sno = sno
  }
  studying() {
    console.log(this.name + " is studying")
  }
  eating() {
    console.log(this.name + " is eating")
  }
  // 重写静态方法
  static staticMethod() {
    super.staticMethod()
    console.log("StudentStaticMethod")
  }
}

var stu = new Student("jack", 18, 150)
console.log(stu) //Student { name: 'jack', age: 18, sno: 150 }
stu.studying()  //jack is studying
stu.eating()    //jack is eating

将以上继承相关ES6代码通过babel转换成ES5后的源码

登录babel网站: babel中文网 找到试一试

WechatIMG126.png