Inheritance way

Many other object-oriented languages support two types of inheritance:

  1. Interface inheritance: Only method signatures are inherited.
  2. Implement inheritance: Inherit the actual method.

Because functions do not have signatures, ECMAScript only supports implementation inheritance, and its implementation inheritance is mainly implemented through a chain of prototypes

Stereotype chain inheritance: Make a stereotype object point to an instance of another class

Use stereotypes to make one reference type inherit the properties and methods of another

Make a prototype object point to an instance of another class. The prototype object’s __proto__ is the prototype pointing to another class, and the constructor of the prototype of another class points to another class

Prototype = new SuperType()

function SuperType() {
    this.property = true;
}
SuperType.prototype.getSuperValue = function(){
    return this.property;
}
function SubType() {
    this.subproperty = false;
}
// Inherits SuperType
SubType.prototype = new SuperType();

// Add or override methods must come after the statement that replaces the stereotype
SubType.prototype.getSubValue = function () {
    return this.subproperty;
}

var instance = new SubType();
console.log(instance.getSuperValue());  //true

console.log(SubType.prototype);  //{ property: true, getSubValue: [Function] }
Copy the code

The instance. GetSuperValue () steps:

  • Instance private properties and private methods do not have getSuperValue
  • 2, through the__proto__Subtype. prototype public property still does not have getSuperValue
  • Subtype.prototype = new SuperType(SubType.prototype__proto__Find the public property getSuperValue for superType. prototype
  • 4, the SuperType. Prototype. This is the instance of getSuperValue
  • Instance is an instance of SubType, so private properties and methods do not have properties
  • 6, through__proto__Find the public property of subtype. prototypeThe output of true

SubType.prototype = new SuperType(); All properties and methods (both plausible and public) in the original SuperType instance now exist in SubType.prototype as well

Instance points to subtype. prototype via __proto__

Subtype. prototype points to supertype. prototype via __proto__

The add or override method must come after the statement that replaces the stereotype

disadvantages

1. Stereotype properties that contain values of reference types are shared by all forces. Is that why you define attributes in constructors instead of stereotype objects

2. When creating instances of subtypes, arguments cannot be passed to the supertype constructor

Borrow constructors (call, apply) : Inherit private properties

1. Call the supertype constructor inside the subtype constructor (the constructor to inherit)

2. Change this from the supertype constructor to an instance object of the subtype constructor

3, generally use call, apply to achieve

function SuperType() {
    this.colors = ['red'.'blue'.'yellow'];
}

function SubType() {
    // Inherits SuperType
    SuperType.call(this)
    // Change this in SuperType to an instance object of SubType
}
var instance = new SubType();
instance.colors.push('black');
console.log(instance.colors);   //[ 'red', 'blue', 'yellow', 'black' ]

var instance2=new SubType();
console.log(instance2.colors);  //[ 'red', 'blue', 'yellow' ]
Copy the code

Passing arguments to the SuperType constructor: supertype.call (this,name)

function SuperType(name) {
    this.name = name;
}

function SubType(name) {
    // Inherits SuperType
    SuperType.call(this,name)
}
var instance = new SubType('aaa');
console.log(instance.name);   //aaa
Copy the code

disadvantages

When we use only borrowed constructor methods, we do not inherit the common methods on the supertype constructor prototype. Methods are defined in the function, so function reuse is out of the question

Combination of inheritance

Inheritance of stereotype properties and methods (public and methods) is implemented using stereotype chains, and inheritance of instance private properties is implemented using borrowed constructors

  1. Use borrowed constructors to inherit instance private properties: supertype.call (this,name)
  2. Inherit public properties and methods
  3. Set constructor to ensure prototype chain integrity
function SuperType(name) {
    this.name = name;
    this.colors=['red'.'blue'.'yellow']
}
SuperType.prototype.sayName=function () {
    console.log(this.name);
}
function SubType(name,age) {
    //1, inherit private attributes
    SuperType.call(this,name)
    this.age=age;
}
// public attributes and methods are inherited
SubType.prototype=new SuperType();
// set constructor to ensure prototype chain integrity
SubType.prototype.constructor=SubType;
// Add a method
SubType.prototype.sayAge=function () {
    console.log(this.age);
}

var instance1 = new SubType('aaa'.18);
instance1.colors.push('black')
console.log(instance1.colors);      //[ 'red', 'blue', 'yellow', 'black' ]
console.log(instance1.name);        //aaa
instance1.sayName();                //aaa
instance1.sayAge();                 / / 18

var instance2 = new SubType('bbb'.16);
console.log(instance2.colors);      //[ 'red', 'blue', 'yellow' ]
console.log(instance2.name);        //bbb
instance2.sayName();                //bbb
instance2.sayAge();                 / / 16

Copy the code

Disadvantages: Multiple calls to the supertype constructor lead to a decrease in efficiency

Parasitic combinatorial inheritance

Parasitic inheritance: Create a function that encapsulates the inheritance process only

This function internally enhances the object in some way (setting constructor, adding methods, etc.) and finally returns the object as if it really did all the work

Parasitic combinatorial inheritance:

  1. Inheriting properties by borrowing constructors,
  2. Through the hybrid form method of prototype chain inheritance method,
  3. Use parasitic inheritance to inherit the stereotype of a supertype

Basic idea: Instead of calling a supertype constructor function to specify a subtype stereotype, only a copy of the supertype stereotype is required

Essence: Use parasitic inheritance to inherit the stereotype of a supertype, and then assign the result to the stereotype of a value type

Basic module

// The function that inherits the method
function inheritPrototype(subType,superType) {
    // Create an object
    var prototype = Object(superType.prototype);
    // Enhance objects
    prototype.constructor=subType;
    // Specify the object
    subType.prototype=prototype;
}
Copy the code

Parasitic combination inherits finished product

// The function that inherits the method
function inheritPrototype(subType,superType) {
    // Create an object
    var prototype = Object(superType.prototype);
    // Enhance objects
    prototype.constructor=subType;
    // Specify the object
    subType.prototype=prototype;
}

function SuperType(name) {
    this.name = name;
    this.colors=['red'.'blue'.'yellow']
}
SuperType.prototype.sayName=function () {
    console.log(this.name);
}

function SubType(name,age) {
    // Inherit attributes (1)
    SuperType.call(this,name)
    this.age=age;
}
// Call the inherited method (2)
inheritPrototype(SubType,SuperType);
// Add a method
SubType.prototype.sayAge=function () {
    console.log(this.age);
}

var instance1 = new SubType('aaa'.18);
instance1.colors.push('black')
console.log(instance1.colors);      //[ 'red', 'blue', 'yellow', 'black' ]
console.log(instance1.name);        //aaa
instance1.sayName();                //aaa
instance1.sayAge();                 / / 18

var instance2 = new SubType('bbb'.16);
console.log(instance2.colors);      //[ 'red', 'blue', 'yellow' ]
console.log(instance2.name);        //bbb
instance2.sayName();                //bbb
instance2.sayAge();                 / / 16
Copy the code