Js itself is a programming language based on object-oriented development. Classes have the following characteristics: encapsulation, inheritance, polymorphism. How are these features represented in JS?

Encapsulation: JS class is also a function, the implementation of a function of the code to encapsulate, in order to achieve low coupling and high cohesion

Polymorphism: includes overloading and overwriting

  • Overloading: The same method has different functions due to different arguments or return values. Overloading is not strictly possible in JS, because in other languages, different arguments can be divided into different functions. If you want js to implement overloading, you can only implement different functions in the same method according to different parameters
  • Override: A subclass overrides a method on its parent class (along with inheritance)

Inheritance: A subclass inherits a method from its parent class

inheritance

In JS, its inheritance is not quite the same as in other languages

The purpose of inheritance: To allow instance colleagues of subclasses to also have private properties and public methods in their parent class

function Parent(){
    this.x = 100
}
Parent.prototype.getX = function getX(){
    return this.x
}
function Child(){
    this.y = 200
}
Child.prototype.getY = function getY(){
    return this.y
}
let c1 = new Child
console.log(c1)
Copy the code

I want c1 to have x and getX as well

Method of inheritance

Prototype inheritance

Make the prototype of the subclass equal to the instance of the parent class

Because instances of subclasses can use subclass private and ancestor public, and instances of superclasses can use parent private and ancestor public.

function Parent(){
    this.x = 100
}
Parent.prototype.getX = function getX(){
    return this.x
}
function Child(){
    this.y = 200
}
Child.prototype = new Parent// Add a sentence
Child.prototype.constructor = Child/ / specify the construct

Child.prototype.getY = function getY(){
    return this.y
}
let c1 = new Child
console.log(c1)
Copy the code

The prototype chain points to the following:

Characteristics of archetypal inheritance

  1. Attribute methods that are private and public in the parent class will eventually be made public by the subclass instance
  2. Unlike in other languages, stereotype inheritance does not copy property methods from the parent class to the child class. Instead, the child class instances are based on__proto__The stereotype chain finds its own custom properties and methods (” point to/find “inheritance rather than copy inheritance)

Rewrite:

C1.__proto__. XXX = XXX Modifies the contents of the subclass prototype (an instance of the original parent class). The modification affects other instances of the subclass, but does not affect the instance of the parent class

C1.__proto__.__proto__. XXX = XXX directly modifies the prototype of the parent class, which affects not only other instances of the parent class, but also instances of other subclasses

callinheritance

In the subclass constructor, the parent class is executed as a normal method and this in the parent class refers to the subclass.

function Parent(){
    this.x = 100
}
Parent.prototype.getX = function getX(){
    return this.x
}
function Child(){
    // In the subclass constructor, the parent class is executed as a normal method.
    //this.x = 100; //this. X = 100; //this.x = 100
    Parent.call(this)
    this.y = 200
}
Child.prototype.getY = function getY(){
    return this.y
}
let c1 = new Child
console.log(c1.getX())
console.log(c1)
Copy the code

This method cannot inherit the public attributes of the parent class.

There are drawbacks to both of these, so what we want is for parent private to become subclass private, and parent common to become subclass common

Parasitic combinatorial inheritance

If you want subclasses to inherit the public attributes of their Parent class, make sure that child.prototype. __proto__ points to Parent. Prototype

Divided into two steps

  1. Parent.call(this)Inherit private properties and methods
  2. Child.prototype.__proto__ = Parent.prototypeInherit public properties and methods

It’s a combination of Call inheritance and alternative prototype inheritance

 function Parent(){
    this.x = 100
}
Parent.prototype.getX = function getX(){
    return this.x
}
function Child(){
    Parent.call(this)/ / 1.
    this.y = 200
}
Child.prototype.__proto__ = Parent.prototype/ / 2.
Child.prototype.constructor = Child/ / 3

Child.prototype.getY = function getY(){
    return this.y
}
let c1 = new Child
console.log(c1.getX())
console.log(c1)
Copy the code

If the browser does not support __proto__ (ie, for example), then we can use Object.create

Object.create

The object.create () method creates a new Object, using an existing Object to provide the __proto__ of the newly created Object

That is, create a new object and point __protot__ to the object passed in

Prototype = object.create (prototype.__proto__ = Parent. Prototype)

Finally, specify constructor

function Parent(){
    this.x = 100
}
Parent.prototype.getX = function getX(){
    return this.x
}
function Child(){
    Parent.call(this)/ / 1.
    this.y = 200
}
Child.prototype.__proto__ = Parent.prototype/ / 2
Child.prototype.constructor = Child/ / 3

Child.prototype.getY = function getY(){
    return this.y
}
let c1 = new Child
console.log(c1.getX())
console.log(c1)
Copy the code

ES6 inheritance

Use the extends keyword. Note: Be sure to add super() to the first line of constructor.

class Parent{
    constructor() {
        this.x = 100
    }
    getX(){// Write the method on the prototype
        return this.x
    }
}
// extends Parent
// Add super() to the first line of constructor.
class Child extends Parent{
    constructor() {
        super(a)this.y = 200
    }
    getY(){
        return this.y
    }
}
let c1 = new Child
console.log(c1.getX())
console.log(c1)
Copy the code

Not adding super() will report an error

'Uncaught ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor'

Doing super() is similar to our previous call inheritance; if we do super(100,200), we pass in the Parent constructor

The end result is similar to parasitic combinatorial inheritance