Diagramming JavaScript Inheritance

Inheritance is one of the components of object-oriented thinking, through which code reuse can be realized and the amount of code can be reduced. Inheritance mainly has two discussion objects: the parent object and the child object. The child object inherits the properties and methods of the parent object, and then the child object can use the properties and methods of the parent object just like using its own methods and properties. Before starting to formally introduce the object, first write the constructors of the parent object and the child object:

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

Parent.prototype.work = function () {
    
    
  console.log(`${
      
      this.name} working...`);
};

function Child(age) {
    
    
  this.age = age;
}

Child.prototype.eat = function () {
    
    
  console.log(`${
      
      this.age}eating...`);
};

As shown below:

inherit-none

The function with the first letter capitalized is a constructor, which is represented by a blue background, and the prototype object of the constructor is placed on top of it, which is represented by a green background. Instances of each constructor are placed below the constructor and are represented in earth tones.

prototypal inheritance

Example of setting the subclass's prototype to the parent class:

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

Parent.prototype.work = function () {
    
    
  console.log(`${
      
      this.name} working...`);
};

// 原型继承
Child.prototype = new Parent("Tom");

Child.prototype.sleep = function () {
    
    
  console.log(`${
      
      this.age} sleeping...`);
};

const c = new Child(9);
//c.eat(); // 失去原来的原型对象
c.work();  // 获得父对象方法
c.sleep();

Illustration:

inherit-proto

advantage

Simple and easy to implement, the new methods and attributes of the parent class can be accessed by subclasses.

shortcoming

1) You can add instance attributes in subclasses. If you want to add new prototype attributes and methods, you need to add them after the new parent class constructor

2) When creating a subclass instance, parameters cannot be passed to the parent class constructor.

borrow constructor inheritance

Borrowing inheritance refers to calling the constructor of the parent class in the constructor of the subclass:

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

Parent.prototype.work = function () {
    
    
  console.log(`${
      
      this.name} working...`);
};

function Child(name, age) {
    
    
  Parent.call(this, name); // 借用继承
  this.age = age;
}

Illustration:

inherit-borrow

advantage

This method is very simple when only the properties of the parent class need to be inherited.

shortcoming

Only the properties of the parent class can be inherited, but the methods of the parent class cannot be inherited, and the properties and methods on the prototype of the parent class cannot be inherited.

Composition inheritance

A perfect inheritance should be: the public methods or properties are on the prototype, and the unique ones are saved by themselves.

Although prototype inheritance can ensure that subclasses can access the properties or methods of the parent class, some properties of the parent class are stored on the prototype of the subclass, but not on their own instance objects. For example, when individuals have their own name properties, you need to add the name property to the instance object instead of the prototype, which is achieved by combining prototypal inheritance and borrowed inheritance:

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

Parent.prototype.work = function () {
    
    
  console.log(`${
      
      this.name} working...`);
};

function Child(name, age) {
    
    
  Parent.call(this, name); // 借用继承
  this.age = age;
}

Child.prototype = new Parent("Tom");
Child.prototype.constructor = Child;
Child.prototype.eat = function () {
    
    
  console.log(`${
      
      this.age}eating...`);
};

const c = new Child("Tom", 12);

Illustration:

inherit-composition

advantage

Compositional inheritance avoids the defects of prototype chain and borrowed constructor, and combines their advantages. Also, using the instanceof operator and the isPrototype() method can also be used to identify objects created based on compositional inheritance.

shortcoming

The supertype constructor is called twice: once when creating the subtype prototype, and once inside the subtype constructor.

prototypal inheritance

Create a new object based on an existing object:

function createAnother(p) {
    
    
  function Child() {
    
    };
  Child.prototype = p;
  return new Child();
}

var p = {
    
    
  name: "父对象",
  say: function () {
    
    },
};

var c = createAnother(p);
console.log(c.name); // "父对象"

Illustration:

inherit-create

Use the shorthand ES5 Object.create() shorthand:

var c = Object.create(p);

Prototypal inheritance is very similar to prototypal inheritance. Using prototypal inheritance for an intermediary object looks like copying an object, but actually turns its prototype into a parent object. In fact it is: c.__proto__=p. Why not just do it?

parasitic inheritance

Parasitic inheritance is achieved by creating a function that is only used to encapsulate the inheritance process, which internally enhances the object in some way, and finally returns this object:

function createChild(parent) {
    
    
  const child = Object.create(parent); // 通过 Object.create() 函数创建一个新对象
  // 增强这个对象
  child.sayGood = function () {
    
    
    alert("hello world!!!");
  };
  return child; // 返回这个对象
}

Parasitic inheritance doesn't look like inheritance in the strict sense of the word.

parasitic compositional inheritance

Properties are inherited by borrowing constructors, and methods are inherited through a hybrid form of the prototype chain. Essentially, parasitic inheritance is used to inherit the prototype of the parent type, and then assign the result to the prototype of the subtype.

function setPrototypeChain(Child, Parent) {
    
    
  const c_prototype = Object.create(Parent.prototype);
  c_prototype.constructor = Child;
  Child.prototype = c_prototype;
}

// 相当于
// Child.prototype.__proto__ = Parent.prototype

Illustration:

inherit-chain

ES6 class inheritance

ES6 uses extends and super to implement inheritance:

class Parent {
    
    
  constructor(name) {
    
    
    this.name = name;
  }
  work() {
    
    
    console.log(`${
      
      this.name} working...`);
  }
}

class Child extends Parent {
    
    
  constructor(name, age) {
    
    
    super(name);
    this.age = age;
  }

  eat() {
    
    
    console.log(`${
      
      this.name} at ${
      
      this.age} is eating...`);
  }
}

const c = new Child("tom", 12);
c.eat();
c.work();

Illustration:

inherit-es6

Thinking: What is the inheritance method implemented by ES6?

Finally put in an eye

♥ I'm a front-end engineer: your sweetheart Sen. Thank you very much for your likes and attention, and welcome everyone to participate in discussions or collaborations.

★ This article is open source , using the CC BY-SA 4.0 protocol , please indicate the source for reprinting: Self-cultivation of front-end engineers . GitHub.com@xiayulu.

★ For creative cooperation or recruitment information, please send a private message or email: [email protected], specifying the subject: creative cooperation or recruitment of front-end engineers .
ayulu/FrontEndCultivation), using CC BY-SA 4.0 agreement , reprint please indicate the source: self-cultivation of front-end engineers . GitHub.com@xiayulu.

★ For creative cooperation or recruitment information, please send a private message or email: [email protected], specifying the subject: creative cooperation or recruitment of front-end engineers .

Guess you like

Origin blog.csdn.net/hongshuteng/article/details/128155257