In-depth explanation of the various methods and advantages and disadvantages of JavaScript inheritance

In-depth explanation of the various methods and advantages and disadvantages of JavaScript inheritance

1. Prototype chain inheritance

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

Parent.prototype.getName = function () {
    console.log(this.name);
}

function Child () {

}

Child.prototype = new Parent();

var child1 = new Child();

console.log(child1.getName()) // kevin

question:

1. The properties of reference types are shared by all instances. For example:

function Parent () {
    this.names = ['kevin', 'daisy'];
}

function Child () {

}

Child.prototype = new Parent();

var child1 = new Child();

child1.names.push('yayu');

console.log(child1.names); // ["kevin", "daisy", "yayu"]

var child2 = new Child();

console.log(child2.names); // ["kevin", "daisy", "yayu"]

2. When creating an instance of Child, you cannot pass parameters to Parent

2. Borrowing constructors (classical inheritance)

function Parent () {
    this.names = ['kevin', 'daisy'];
}

function Child () {
    Parent.call(this);
}

var child1 = new Child();

child1.names.push('yayu');

console.log(child1.names); // ["kevin", "daisy", "yayu"]

var child2 = new Child();

console.log(child2.names); // ["kevin", "daisy"]

advantage:

  • 1. Prevents properties of reference types from being shared by all instances
  • 2. You can pass parameters to Parent from Child

For example:

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

function Child (name) {
    Parent.call(this, name);
}

var child1 = new Child('kevin');

console.log(child1.name); // kevin

var child2 = new Child('daisy');

console.log(child2.name); // daisy

shortcoming:

  • Methods are defined in the constructor, and each time an instance is created, the method is created again.

3. Combination inheritance

Prototype inheritance and classical inheritance work together.

function Parent (name) {
    this.name = name;
    this.colors = ['red', 'blue', 'green'];
}

Parent.prototype.getName = function () {
    console.log(this.name)
}

function Child (name, age) {

    Parent.call(this, name);

    this.age = age;

}

Child.prototype = new Parent();

var child1 = new Child('kevin', '18');

child1.colors.push('black');

console.log(child1.name); // kevin
console.log(child1.age); // 18
console.log(child1.colors); // ["red", "blue", "green", "black"]

var child2 = new Child('daisy', '20');

console.log(child2.name); // daisy
console.log(child2.age); // 20
console.log(child2.colors); // ["red", "blue", "green"]

Advantages: It combines the advantages of prototype chain inheritance and constructor function and is the most commonly used inheritance mode in JavaScript.

4. Prototype inheritance

function createObj(o) {
    function F(){}
    F.prototype = o;
    return new F();
}


It is a simulated implementation of ES5 Object.create , which uses the passed object as the prototype of the created object.

Disadvantages: Property values ​​containing reference types always share the corresponding values, just like prototype chain inheritance.

var person = {
    name: 'kevin',
    friends: ['daisy', 'kelly']
}

var person1 = createObj(person);
var person2 = createObj(person);

person1.name = 'person1';
console.log(person2.name); // kevin

person1.firends.push('taylor');
console.log(person2.friends); // ["daisy", "kelly", "taylor"]

Note: When the value of person1.name is modified, the value of person2.name does not change. This is not because person1 and person2 have independent name values, but because person1.name = 'person1' adds name value to person1 , rather than modifying the name value on the prototype.

5. Parasitic inheritance

Create a function that is used only to encapsulate the inheritance process, which internally enhances the object in some form and finally returns the object.

function createObj (o) {
    var clone = object.create(o);
    clone.sayName = function () {
        console.log('hi');
    }
    return clone;
}

Disadvantages: Like the borrowed constructor pattern, a method is created each time an object is created.

6. Parasitic Combinatorial Inheritance

For your convenience, let's repeat the combined inheritance code here:

function Parent (name) {
    this.name = name;
    this.colors = ['red', 'blue', 'green'];
}

Parent.prototype.getName = function () {
    console.log(this.name)
}

function Child (name, age) {
    Parent.call(this, name);
    this.age = age;
}

Child.prototype = new Parent();

var child1 = new Child('kevin', '18');

console.log(child1)

The biggest disadvantage of composite inheritance is that the parent constructor is called twice.

Once is when setting the prototype of a subtype instance:

Child.prototype = new Parent();

Once when creating an instance of the subtype:

var child1 = new Child('kevin', '18');

Recall the simulation implementation of new. In fact, in this sentence, we will execute:

Parent.call(this, name);

Here, we call the Parent constructor again.

So, in this example, if we print the child1 object, we will find that Child.prototype and child1 have a property called colors with the value ['red', 'blue', 'green']。

So how can we strive for excellence and avoid repeated calls this time?

What if we don’t use Child.prototype = new Parent() but instead let Child.prototype access Parent.prototype indirectly?

See how it is implemented:

function Parent (name) {
    this.name = name;
    this.colors = ['red', 'blue', 'green'];
}

Parent.prototype.getName = function () {
    console.log(this.name)
}

function Child (name, age) {
    Parent.call(this, name);
    this.age = age;
}

// Three key steps var F = function () {};

F.prototype = Parent.prototype;

Child.prototype = new F();


var child1 = new Child('kevin', '18');

console.log(child1);

Finally, we encapsulate this inheritance method:

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

function prototype(child, parent) {
    var prototype = object(parent.prototype);
    prototype.constructor = child;
    child.prototype = prototype;
}

// When we use:
prototype(Child, Parent);

Quoting the praise of parasitic combinatorial inheritance in "Advanced JavaScript Programming":

The efficiency of this approach is that it only calls the Parent constructor once, and thus avoids creating unnecessary, redundant properties on Parent.prototype . At the same time, the prototype chain remains unchanged; therefore, instanceof and isPrototypeOf can still be used normally. Developers generally believe that parasitic compositional inheritance is the most ideal inheritance paradigm for reference types.

This concludes this article on in-depth explanation of the various ways of inheritance in JavaScript and their advantages and disadvantages. For more information on various ways of inheritance in JavaScript and their advantages and disadvantages, please search for previous articles on 123WORDPRESS.COM or continue to browse the related articles below. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Detailed explanation of Js class construction and inheritance cases
  • An article teaches you JS function inheritance
  • How much do you know about JavaScript inheritance?
  • Differences between ES6 inheritance and ES5 inheritance in js
  • A brief talk about JavaScript parasitic composition inheritance
  • JavaScript object-oriented class inheritance case explanation

<<:  Docker Nginx container and Tomcat container to achieve load balancing and dynamic and static separation operations

>>:  Detailed explanation of character sets and validation rules in MySQL

Recommend

Which loop is the fastest in JavaScript?

Knowing which for loop or iterator is right for o...

Four ways to compare JavaScript objects

Table of contents Preface Reference Comparison Ma...

JS achieves five-star praise effect

Use JS to implement object-oriented methods to ac...

10 Popular Windows Apps That Are Also Available on Linux

According to data analysis company Net Market Sha...

Some ways to eliminate duplicate rows in MySQL

SQL statement /* Some methods of eliminating dupl...

Web Design Experience: Efficiently Writing Web Code

Originally, this seventh chapter should be a deep ...

How to install Chrome browser on CentOS 7

This article introduces how to install Chrome bro...

Detailed usage of kubernetes object Volume

Overview Volume is the abstraction and virtualiza...

MySQL database table partitioning considerations [recommended]

Table partitioning is different from database par...

Detailed explanation on how to deploy H5 games to nginx server

On the road to self-learning game development, th...

Minimalistic website design examples

Web Application Class 1. DownForEveryoneOrJustMe ...

Solution to MySQL Chinese garbled characters problem

1. The Chinese garbled characters appear in MySQL...

mysql5.7.19 winx64 decompressed version installation and configuration tutorial

Recorded the installation tutorial of mysql 5.7.1...

Install tomcat and deploy the website under Linux (recommended)

Install jdk: Oracle official download https://www...

Detailed explanation of the WeChat applet request pre-processing method

question Because some of our pages request data i...