Five ways to implement inheritance in js

Five ways to implement inheritance in js

Borrowing Constructors

The basic idea of ​​this technique is simple: call the supertype constructor from within the subtype constructor. Also, a function is nothing more than an object that executes code in a specific environment, so by using the apply() and call() methods you can also execute the constructor on a newly created object.

function Box(name){
 this.name = name
}
Box.prototype.age = 18

function Desk(name){
 Box.call(this, name) // Object impersonation, object impersonation can only inherit information in the constructor}

var desk = new Desk('ccc')
console.log(desk.name) // --> ccc
console.log(desk.age) // --> undefined

From this we can see that only instance properties are inherited, and the properties on the prototype are inaccessible. This pattern solves two problems: it allows parameter passing and inheritance, but without a prototype, it cannot be reused.

Composition inheritance

function Box(name){
 this.name = name
}
Box.prototype.run = function (){
 console.log(this.name + 'Running...')
}

function Desk(name){
 Box.call(this, name) // object impersonation}

Desk.prototype = new Box() // prototype chain var desk = new Desk('ccc')
console.log(desk.name) // --> ccc
desk.run() // --> ccc is running...

The idea behind this inheritance method is to use the prototype chain to inherit prototype properties and methods, and to use the constructor to inherit instance properties.

Prototypal inheritance

Prototype inheritance: Prototypes can be used to create new objects based on existing objects without having to create custom types. Speaking of this, we must mention a person. Douglas Crockford gave a method in an article he wrote in 2006, "Prototype inheritance in Javascript":

function object(o) { // pass a literal function function F(){} // create a constructor F.prototype = o; // assign the literal function to the prototype of the constructor return new F() // finally return the instantiated constructor }

Consider the following example:

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

var box = {
 name: 'ccc',
 age: 18,
 family: ['brother','sister']
}

var box1 = obj(box)
console.log(box1.name) // --> ccc
box1.family.push('sister')
console.log(box1.family) // --> ["brother", "sister", "sister"]

var box2 = obj(box)
console.log(box2.family) // --> ["brother", "sister", "sister"]

Because the implementation logic of the above code is very similar to prototype chain inheritance, the reference array, that is, the family attribute, is shared.

Parasitic inheritance

function obj(o) {
 function F (){}
 F.prototype = o;
 return new F()
}
function create(o){
 var clone = obj(o) // Create a new object by calling a function clone.sayName = function(){ // Enhance this object in some way console.log('hi')
 }
 return clone // Return this object }

var person = {
 name: 'ccc',
 friends: ['aa','bb']
}

var anotherPerson = create(person)
anotherPerson.sayName() // --> hi

The code in this example returns a new object, anotherPerson, based on person. The new object not only has all the properties and methods of person, but also has its own sayHi() method. Parasitic inheritance is also a useful pattern in situations where you are primarily concerned with objects rather than custom types and constructors. Using parasitic inheritance to add functions to objects will reduce efficiency due to the inability to reuse functions, which is similar to the constructor pattern.

Parasitic Combinatorial Inheritance

As mentioned earlier, composite inheritance is the most commonly used inheritance mode in JavaScript, but it also has its own shortcomings. The biggest problem with composite inheritance is that no matter what the circumstances, the supertype constructor is called twice: once when creating the subtype prototype, and once inside the subtype constructor. Yes, the subtype will eventually contain all the instance properties of the supertype object, but we have to rewrite these properties when calling the subtype constructor. Let's take a look at the following example:

function SuperType(name){
 this.name = name;
 this.colors = ['red','black']
}
SuperType.prototype.sayName = function (){
 console.log(this.name)
}
function SubType(name, age){
 SuperType.call(this, name) // Second call to SuperType
 this.age = age
}

SubType.prototype = new SuperType() // First call to SuperType
SubType.prototype.constructor = SubType
SubType.prototype.sayAge = function (){
 console.log(this.age)
}

The first time the SuperType constructor is called, SubType.prototype gets two properties: name and colors. They are all instance properties of SuperType, but now they are located in the prototype of SubType. When the SubType constructor is called, the SuperType constructor is called again, which again creates the instance attributes name and colors on the new object. Therefore, these two properties mask the two properties with the same name in the prototype. That is, there are two sets of name and colors attributes: one on the instance, and one on the prototype. This is the result of calling the SuperType constructor twice. The solution to this problem is parasitic combination inheritance.
The so-called parasitic combinatorial inheritance is to inherit properties by borrowing constructors and to inherit methods through a hybrid form of prototype chains. The basic idea behind this is that there is no need to call the supertype's constructor in order to prototype a subtype; all we need is a copy of the supertype's prototype. Essentially, you use parasitic inheritance to inherit from the supertype's prototype and then assign the result to the subtype's prototype. The basic pattern of parasitic composite inheritance is as follows:

function object(o) {
 function F (){}
 F.prototype = o;
 return new F()
}
function inheritPtototype(subType, superType){
 var prototype = object(superType.prototype) // create object prototype.constructor = subType // enhance object subType.prototype = prototype // specify object }

function SuperType(name){
 this.name = name
 this.colors = ['red', 'white']
}

SuperType.prototype.sayName = function(){
 console.log(this.name)
}

function SubType(name,age){
 SuperType.call(this,name)
 this.age = age
}

inheritPtototype(SubType, SuperType)

SubType.prototype.sayAge = function(){
 console.log(this.age)
}

var instance = new SubType('ccc', 18)

instance.sayName() // --> ccc
instance.sayAge() // --> 18
console.log(instance)

The structure printed out by the console:

Detailed diagram:

The efficiency of this example is that it only calls the SuperType constructor once, and thus avoids creating unnecessary, redundant properties on SubType.prototype. At the same time, the prototype chain remains unchanged; therefore, instanceof and isPrototypeOf() can still be used normally. This is also the inheritance method used by many large companies.

The above are the details of the five methods of implementing inheritance in js. For more information about js inheritance, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • Detailed explanation of native Javascript inheritance methods and their advantages and disadvantages
  • Several ways to implement inheritance in JavaScript
  • JS inheritance implementation method and advantages and disadvantages detailed explanation
  • JavaScript class inheritance multiple implementation methods
  • JavaScript uses the prototype property to implement inheritance operations example
  • How to implement inheritance using JavaScript

<<:  Linux file systems explained: ext4 and beyond

>>:  What is table partitioning and partitioning? MySql database partitioning and table partitioning method

Recommend

Gallery function implemented by native Js

Table of contents The first The second Native Js ...

How to solve the Mysql transaction operation failure

How to solve the Mysql transaction operation fail...

Vue uses three methods to refresh the page

When we are writing projects, we often encounter ...

Analysis of the principle of Nginx using Lua module to implement WAF

Table of contents 1. Background of WAF 2. What is...

How to isolate users in docker containers

In the previous article "Understanding UID a...

Example code for hiding element scrollbars using CSS

How can I hide the scrollbars while still being a...

How to remotely log in to the MySql database?

Introduction: Sometimes, in order to develop a pr...

mysql obtains statistical data within a specified time period

mysql obtains statistical data within a specified...

Tutorial on installing mysql5.7.18 on mac os10.12

I searched the entire web and found all kinds of ...

Install Kafka in Linux

Table of contents 1.1 Java environment as a prere...

How to check if the firewall is turned off in Linux

1. Service method Check the firewall status: [roo...

About MySQL 8.0.13 zip package installation method

MySQL 8.0.13 has a data folder by default. This f...