The Broken Ethical Relationship: The Inheritance of JS

In JavaScript, inheritance is an important concept that allows us to create an object and inherit properties and methods from other objects. There are many ways to implement inheritance, each with its own advantages, disadvantages, and applicable scenarios. Below we will explain in detail how each inheritance method works and how to use it.

6 methods of JavaScript inheritance: 1. Prototype chain inheritance, the focus of which is to make the prototype of the new instance equal to the instance of the parent class; 2. Borrowing constructor inheritance (also called fake object or classic inheritance); 3. Combination inheritance (combined prototype Chain inheritance and borrowed constructor inheritance); 4. Prototypal inheritance; 5. Parasitic inheritance; 6. Parasitic combined inheritance.

1. Prototype Chain Inheritance

Code:

function Parent() { this.name = 'Parent'; }
        Parent.prototype.sayHello = function () { console.log('Hello from ' + this.name); }
        function Child() { this.name = 'Child'; }
        Child.prototype = new Parent();
        var child = new Child(); child.sayHello(); // Output: Hello from Child

2. Constructor inheritance

Constructor inheritance: Modify this in the parent class constructor to point to the instantiated object of the subclass constructor

advantage:

1. Solve the first shortcoming of prototype chain inheritance and can pass parameters to the parent class

2. You can inherit the properties of multiple constructors (call multiple)

shortcoming:

1.*Members that do not inherit the prototype of the parent class*

2. The reusability of the parent class constructor cannot be achieved (every time an instantiated object s is created, this of the parent class constructor will be changed again)

Code:

function Parent(name) {
            this.name = name;
        }
        Parent.prototype.sayHello = function () {
            console.log('Hello from ' + this.name);
        }
        function Child(name) {
            Parent.call(this, name);
        }
        var child = new Child('Child');
        child.sayHello(); // Output: Hello from Child

3. Composite inheritance

Combination inheritance combines the advantages of prototype chain inheritance and constructor inheritance. Inherit properties by calling the parent class constructor, use the parent class instance as the prototype object of the child class, and inherit the parent class’s methods.

 function Parent(name) {
            this.name = name;
        }
        Parent.prototype.sayHello = function () {
            console.log('Hello from ' + this.name);
        }
        function Child(name) {
            Parent.call(this, name);
        }
        Child.prototype = new Parent();
        Child.prototype.constructor = Child;
        var child = new Child('Child');
        child.sayHello(); // Output: Hello from Child

4. Prototype Style Inheritance

Advantages: simple, convenient, can inherit the methods and attributes of the prototype
Missing order: only the prototype can be inherited, and it is inconvenient to pass parameters

function Parent(n){
        this.name = n;
    }
    Parent.prototype.skill = function(){
        console.log(this.name + "is an appraiser"); //Da Laowang is an appraiser
                                                 //Xiao Lao Wang is an appraiser
    }

    function Child(n){
        this.name = n;
    }

    // Note: Deep and shallow copies of objects
    for(var i in Parent.prototype){
        Child.prototype[i] = Parent.prototype[i];
    }


    var p = new Parent("大老王");
    console.log(p) //Parent {name: "大老王"}
    p.skill();

    var c = new Child("小老王");
    console.log(c) //Child {name: "小老王"}
    c.skill();

5. Parasitic Inheritance

Parasitic inheritance (Parasitic Inheritance) is a prototype-based inheritance method. It creates a function only to encapsulate the inheritance process. This function internally calls prototypal inheritance to create an object, then enhances the object, and finally returns this object.

The basic steps:

  1. Create a function that encapsulates the inheritance process, which we call a “parasitic function”.

  2. Inside the parasitic function, a new object is created in some way, and this new object will serve as the inherited object.

  3. Inside the parasitic function, you can add properties and methods that need to be inherited by the new object.

  4. Finally, return this new object as the inheritance result

function createPerson(name) {
  var person = {};
  person.name = name;
  
  person.sayHello = function() {
    console.log("Hello, my name is " + this.name);
  };
  
  return person;
}
 
var john = createPerson("John");
john.sayHello(); // Output: Hello, my name is John

6. Parasitic Inheritance

Parasitic combined inheritance, from the name, can be understood as a combination of parasitic inheritance and combined inheritance. Developers generally believe that parasitic combined inheritance is the most ideal inheritance paradigm for reference types. To understand parasitic composable inheritance, first learn about parasitic inheritance and composable inheritance.

  1. Methods of parent classes can be reused
  2. Reference properties of parent classes will not be shared
  3. Subclasses can pass parameters to the parent class when constructing an instance.
    However, the parent class constructor is called twice in combined inheritance.
function Parent(name) {
  this.name = name;
}
 
Parent.prototype.sayHello = function() {
  console.log("Hello, my name is " + this.name);
};
 
function Child(name, age) {
  Parent.call(this, name);
  this.age = age;
}
 
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
 
Child.prototype.sayAge = function() {
  console.log("I am " + this.age + " years old.");
};
 
var john = new Child("John", 25);
john.sayHello(); // Output: Hello, my name is John
john.sayAge(); // Output: I am 25 years old.