The nature of inheritance: Subclasses inherit the properties and methods of their parent class. (The goal is to allow instances of subclasses to call the attributes and methods of their parent classes.)

Inheritance in ES5

  • Prototype inheritance
    • Principle: Keep attributes and methods in a parent class on the prototype chain of a subclass instance

      CHILD.prototype = new PARENT()

      CHILD.prototype.constrctor = CHILD

    • Features:

      • Instead of copying inheritance like in other languages, which copies attributes and methods of the parent class into subclasses for subclasses to call, it places instances of the parent class on the prototype chain of the subclass instance, and the instance wants to call those methods based on the __proro__ prototype chain lookup mechanism.
      • Subclasses can override methods on the parent class, causing other instances of the parent class to be affected as well.
      • Property methods that are private or public in the parent class will eventually become public in the child class.
// The prototype chain is inherited at 🌰
/ / parent class
function Parent(x) {
    this.x = x
} 
Parent.prototye.getX = function() {
    console.log(this.x)
}
/ / subclass
function Child(y) {
    this.y = y
}
/ / inheritance
Child.prototype = new Parent('y') // The prototype of a subclass points to an instance of its parent class
Child.prototype.constrctor = Child // Ensure the integrity of the subclass constructor
Child.prototype.getY = function() {
    console.log(this.y)
}
const child = new Child('x')
child.y // y successfully accessed the subclass properties
child.x // x successfully accessed the parent class attribute
child.getX() // x successfully called the parent method
child.getY() // y successfully called the subclass's own method

// Subclasses can modify the parent class via child.prototype.__proto__ and affect other instances of the parent class
Child.prototype.__proto__.other = function () {
    console.log('other')}const parent = new Parent(200)
parent.other() // other
Copy the code
  • The CALL to inherit
    • Principle:
      • Using the PARENT method as a normal function in a CHILD method, and referring to this in PARENT to an instance of the CHILD, is equivalent to setting private properties and methods on the CHILD instance
    • Features:
      • Only attributes and methods that are private to the PARENT class can be inherited (because PARENT is executed as a normal function, regardless of the attributes and methods on its prototype)
      • Parent class private becomes subclass private
// CALL inherit 🌰
/ / parent class
function Parent(x) {
    this.x = x
    this.thisGetX = function () {
        console.log(this.x)
    }
}
Parent.prototype.getX = function () {
    console.log(this.x)
}
/ / subclass
function Child(y) {
    // this => instance of Child
    Parent.call(this.200)
    this.y = y
}
Child.prototype.getY = function () {
    console.log(this.y)
}

const child = new Child(100)
console.log(child.x) // The parent attribute was successfully accessed
child.getX() // An error was reported that attributes and methods on the parent prototype chain could not be accessed
Copy the code
  • Parasitic combinatorial inheritance
    • Principle: CALL inheritance + bud is similar to prototype inheritance
    • Features:
      • Parent class private and public attributes and methods are common and private methods of subclass instances, respectively (recommended)
// Parasitic combination inheritance 🌰
/ / parent class
function Parent(x) {
    this.x = x
    this.thisGetX = function () {
        console.log(this.x)
    }
}
Parent.prototype.getX = function () {
    console.log(this.x)
}

/ / subclass
function Child(y) {
    // this => instance of Child
    Parent.call(this.200)
    this.y = y
}

// object. create => create an empty Object with __proto__ pointing to Parent. Prototype
Child.prototype = Object.create(Parent.prototype)
Child.prototype.constructor = Child
const child = new Child(100)
console.log(child.x) // The parent attribute was successfully accessed
child.getX() // An error was reported that attributes and methods on the parent prototype chain could not be accessed

// Implement the object.create method
function create(obj) {
    function Fn()
  Fn.prototype = obj
  return new Fn()}Copy the code

Inheritance in ES6

  • class
    • Class CHILD extends Parent {} => CHILD. Prototype._ proto_ = Parent
    • Features:
      • A subclass inheriting from its parent class may disdain constructor, and once written, the first sentence in constructor must be super(), which acts like call inheritance.
/ / parent class
// Classes created based on classes in ES6 cannot be executed as normal functions and do not allow redirection of archetypes
class Parent {
    constructor(x) {
        this.x = x
    }
    getX() {
        console.log(this.x)
    }
}
/ / subclass
// class Child {
// constructor(y) {
// this.y = y
/ /}
// getY() {
// console.log(this.y)
/ /}
// }
// Inheritance in ES6
class Child extends Parent {
    constructor(y) {
        super(200)
        this.y = y
    }
    getY() {
        console.log(this.y)
    }
}
const child = new Child(100)
console.log(child.x) // The parent attribute was successfully accessed
child.getX() // The parent method was successfully called
Copy the code