skip to content

JavaScript
JS 的三种继承

ES6 Class

class Person {
  constructor(name, age) {
    this.name = name
    this.age = age
  }
  getInfo() {
    return `name : ${this.name} ${this.age}`
  }
}

class Student extends Person {
  constructor(name, age, grade) {
    super(name, age)
    this.grade = grade
  }
  getGrade() {
    return `grade : ${this.grade}`
  }
}

const s1 = new Student('Jack', 17, 100)
const s2 = new Student('Tim', 19, 90)

寄生组合式继承

function Person(name, age) {
  this.name = name
  this.age = age
}

Person.prototype.getInfo = function () {
  return `name : ${this.name} ${this.age}`
}

function Student(name, age, grade) {
  Person.call(this, name, age)
  this.grade = grade
}

Student.prototype = Object.create(Person.prototype)

Student.prototype.getGrade = function () {
  return `grade : ${this.grade}`
}

Student.prototype.constructor = Student

const s1 = new Student('Jack', 17, 100)
const s2 = new Student('Tim', 19, 90)

OLOO

OLOO === Objects Linked to Other Objects

// 使用 OLOO 的方式重构继承
// 创建 Person 对象
const Person = {
  init(name, age) {
    this.name = name
    this.age = age
    return this
  },
  getInfo() {
    return `name : ${this.name}\n age : ${this.age}`
  }
}
const p1 = Object.create(Person).init('Tim', 20)

/* 
  使用 Object.create 创建一个以 Person 为原型的 Student 对象
  Student 的 init 方法在原型链上会先比 Person 的 init 方法先被找到,所以不用担心
  ---- Student 结构图 ----
  ➡️ getGrade: ƒ ()
  ➡️ init: ƒ (name, age, grade)
  ⬇️ __proto__:
    ➡️ getInfo: ƒ getInfo()
    ➡️ init: ƒ init(name, age)
    ➡️ __proto__: Object 
*/
const Student = Object.create(Person)
Student.init = function (name, age, grade) {
  Person.init.call(this, name, age)
  this.grade = grade
  return this
}
Student.getGrade = function () {
  return `grade : ${this.grade}`
}
const s1 = Object.create(Student).init('Jack', 17, 100)
const s2 = Object.create(Student).init('Tim', 19, 90)