The application of inheritance relationship in JS

Keywords: Javascript Attribute Programming

Preface

An important aspect of object-oriented programming is object inheritance. By inheriting B object, A object can directly own all the properties and methods of B object. This is very useful for code reuse. Traditionally, the inheritance of JavaScript language is not through class, which needs to be implemented by prototype mechanism or by apple and call methods. Class syntax is introduced in ES6, so class based inheritance appears.

What does inheritance solve?

Why use inheritance? What problem does inheritance solve? Let's stop selling here and give the answer directly. Inheritance is to solve the defects of constructors. It can not share properties among multiple instances of the same constructor, which results in a waste of system resources. Let's briefly analyze the following examples.

Example 1:

function Cat (name, color) {
  this.name = name;
  this.color = color;
}

var cat1 = new Cat('Big wool', 'white');

cat1.name // 'Mao'
cat1.color // 'white'

In the above code, Cat function is a constructor. The name attribute and color attribute are defined inside the function. All instance objects (cat1) will generate these two attributes. Let's transform example 1.

Example 2:

function Cat(name, color) {
  this.name = name;
  this.color = color;
  this.meow = function () {
    console.log('Meow meow');
  };
}

var cat1 = new Cat('Big wool', 'white');
var cat2 = new Cat('20 Fen', 'black');

cat1.meow === cat2.meow
// false

cat1 and cat2 in example 2 are two instances of the same constructor, both of which have the meow method. Since the meow method is generated on each instance object, two instances are generated twice. ok, I think everyone here is very clear. However, when an instance is created, a new function method will be created, which is unnecessary and wastes system resources. Because all meow methods are the same behavior, they can be shared and reused.

Inherited applications

Anything existing must be reasonable. In the above example, we can roughly understand what inheritance is for. Now we have to know how it works, that is, how does inheritance come true? Before you start, look at all the methods you need to implement inheritance.

  • Prototype chain inheritance
  • Constructor inheritance
  • call method inheritance
  • Apple method inheritance
  • Combinatorial inheritance
  • ES6 implementation inheritance

1. Prototype chain inheritance

The prototype of the constructor is set as the instance object of another constructor, so that all the properties and methods of another prototype object can be inherited, and the prototype chain can be formed finally.

The subclass appends all the attributes and methods in the parent class to the subclass through prototype to realize inheritance. In order for a subclass to inherit the properties (including methods) of the parent class, you first need to define a constructor, and then assign a new instance of the parent class to the constructor prototype. See the following code for details.

function parent(){
    this.name="garuda";
}
function child(){
    this.sex="man"
}
child.prototype=new parent();//Core: the child class inherits the parent class and forms a chain through the prototype
var test=new child();
console.log(test.name);
console.log(test.sex);

In js, the inherited function is called supertype (parent class, base class), and the inherited function is called subtype (child class, derived class).

There are two problems in using stereotype inheritance: one is that overriding a stereotype with facets breaks the relationship, using a stereotype with a reference type, and the other is that a subtype cannot pass parameters to a supertype.

2. Borrowing constructor inheritance

In order to solve the problem of reference type value in the prototype, we started to use borrowing constructors, also known as fake objects or classic inheritance

function parent(){
    this.name="garuda";
}
function child(){
    parent.call(this);//Core: use the parent type constructor to strengthen the child type (pass parameter)
}
var test =new parent();
console.log(test.name);

The problem is that all types can only use the constructor mode (because the methods defined in the supertype prototype are not visible to the subtypes), so the methods are defined in the constructor, so function reuse is impossible.

3. call method inheritance

callThe method isFunctionMethods in classcallThe value of the first parameter of the method is assigned to the class(That is, method.)Appeared inthiscallThe second parameter of the method is assigned to the class in turn(That is, method.)Accepted parameters (parameter list).

function test(str){
    alert(this.name + " " + str);
  }
var object = new Object();
object.name = "zhangsan";
test.call(object,"langsin");
//At this point, the first parameter value object is passed to this in the test class (i.e. method),
// The second parameter "langsin" is assigned to the str of the test class (that is, method)
  function Parent(username){
    this.username = username;
    this.hello = function(){
      alert(this.username);
    }
  }
  function Child(username,password){
    Parent.call(this,username); 
    this.password = password;
    this.world = function(){
      alert(this.password);
    }
  }
  var parent = new Parent("zhangsan");
  var child = new Child("lisi","123456");
  parent.hello();
  child.hello();
  child.world();

4. apply method inheritance

The apply method accepts two parameters. The first parameter is the same as the first parameter of the call method, i.e. it is assigned to this in the class (i.e. method). The second parameter is array type. Each element in this array is assigned to the parameter (group of parameters) accepted by the class (i.e. method) in turn.

function Parent(username){
    this.username = username;
    this.hello = function(){
      alert(this.username);
    }
  }
  function Child(username,password){
    Parent.apply(this,new Array(username));
    this.password = password;
    this.world = function(){
      alert(this.password);
    }
  }
  var parent = new Parent("zhangsan");
  var child = new Child("lisi","123456");
  parent.hello();
  child.hello();
  child.world();

5. Combination inheritance (prototype chain and constructor combination)

Also known as pseudo classic inheritance, it combines prototype chain and borrowed constructor technology. Prototype chain is used to inherit prototype properties and methods, while constructor is used to inherit instance properties.

function parent(){
    this.name="garuda";
}
function borther(){
    return this.name;
}
function child(){
    parent.call(this)
}
child.prototype=new parent();
var test=new parent();
console.log(test.borther())

In fact, the constructor is borrowed to solve the problem that the reference type property of the prototype is shared in all instances in the prototype chain inheritance.

6. ES6 implementation inheritance

The class of ES6 is a syntactic sugar, and its essence is a function. However, the above process of using class to implement inheritance is still based on the prototype chain (is it exactly the same as ES5's)

// ES6 writing
class Human{
     constructor(name){
         this.name = name
     }
     run(){
         console.log("My name is"+this.name+",I am running.")
         return undefined
     }
 }
 class Man extends Human{ // extends implements the above inheritance process
     constructor(name){
         super(name) // Call constructor: 'superclass'
         this.gender = 'male'
     }
     fight(){
         console.log('Paste your bear face.')
     }
 }

summary

The inheritance relationship in JS is a very important technical knowledge, which is often used in the actual development. Children's shoes that don't know need to learn and understand quickly!

Posted by sheriff on Fri, 01 Nov 2019 09:30:39 -0700