current position:Home>Have you learned the 7 methods of JS inheritance?
Have you learned the 7 methods of JS inheritance?
2021-08-27 08:41:43 【Xiao Cheng】
This is my participation 8 The fourth of the yuegengwen challenge 23 God , Check out the activity details :8 Yuegengwen challenge
Hello everyone , I'm Xiao Cheng's classmate , This article mainly writes JavaScript Medium 7 There are two ways of inheritance , Deeply understand the problems of each method and how the new method solves the problems
Thank you very much for reading , You are welcome to correct the wrong places
May your life be bright , Everything is lovely
Preface
In the last article, we explained the mechanism of prototype chain and some properties related to prototype , What is closely related to the prototype chain is inheritance , Why do you say that ?
stay 《JavaScript Advanced programming 》 On , There's a phrase
“ Implementing inheritance is ECMAScript
The only way to support inheritance , And this is mainly through Prototype chain To achieve .”
As one can imagine , Prototype chain plays an important role in inheritance
Before the full text begins , Let's take a look at the outline of this article
Closely related 6 There are two ways of inheritance
stay ES6 Before coming , be based on ES5 Inheritance of realization , In each generation, the problems brought by the previous generation are optimized , This is also JavaScript What is worth learning in language , Have a problem , solve the problem , Continuous optimization , Next, let's see how they are implemented step by step
One 、 Prototype chain inheritance
1. The basic idea
The basic idea of prototype chain inheritance is through Prototype To inherit properties and methods of multiple reference types
Realized The basic idea Is to instantiate an object using a constructor , adopt new
keyword , take The instance object of the constructor Prototype object as subclass function
2. Implementation method
// Define the parent function
function Father() {
// Define parent class properties
this.name = 'father'
}
// Add methods to the prototype of the parent class
Father.prototype.say = function () {
console.log(' I'm daddy ');
}
// Create subclass functions
function Son() {}
// Implementation inheritance
Son.prototype = new Father()
// Print reference
console.log(Son.prototype) // Father {name: "father"}
Copy code
Let's explain the code above , First, a parent function and a child function are defined , Added some properties and methods
The key to inheritance is Son.prototype = new Father()
. How does it understand
First of all, we need to understand new
Operator execution
- Create an empty object
- Inherit function prototype , Put this new object's
__proto__
Property is assigned to the prototype object of the constructor - Inside the constructor
this
Point to a new object - Execute function body
- Return to this new object
got it new
After , We can know when we are new Father()
In operation , This step will be Father
The prototype object of the constructor is packaged to Father
Instance object of , That is to say father.__proto__ = Father.prototype
, Change here, that is Son.prototype.__proto__ = Father.prototype
, In this way, it is The instance object of the parent class is used as the prototype of the child class , This also enables the connection between the child class and the parent class
Critical code :son.prototype = new Father()
3. The problem is
Through the above analysis , On the whole, I don't feel anything wrong , But let's take a look at this example
function Father() {
// Define the parent class attribute as the reference data type
this.a = [1, 2, 3, 4]
}
Copy code
We put the above code in a
Change the value of to the reference data type , We know that for a reference data type, only the reference to it will be saved , That's the memory address .
Let's first create two subclasses that inherit this parent class son1 ,son2
let son1 = new Son()
let son2 = new Son()
Copy code
Then we want to son1
Medium a
Add a value to the array 5 , We'll do this
son1.a.push(5)
Copy code
Don't think too much. son1
You must have successfully added , But let's print it again son2
, We'll find it a
The array has also been changed
This is the problem that the reference data type is shared by subclasses caused by the prototype chain inheritance
4. Advantages and disadvantages
advantage :
- Methods of the parent class can be reused
- It's easy to operate
shortcoming
- For reference data types, data is shared by subclasses , That is, change one, and everything else will change
- When creating a subclass instance , Cannot pass parameter to parent constructor , inflexible .
Two 、 Stealing constructor inheritance
In order to solve the problem that reference values cannot be shared due to the inheritance of prototype chain , Thus, a kind of “ Stealing constructor inheritance ” The way
1. The basic idea
In order to achieve Reference value sharing The problem of , We can't directly use the reference value on the prototype object for subclasses .
therefore , You can call the parent class constructor in the child class constructor .
Let's start with a simple piece of code
function Son() {
this.a = [1, 2, 3, 4]
}
Copy code
If we rewrite the subclass code like this , What will happen ?
When we go through Son
Constructor instantiates an instance object , Variables in each instance object a
They're all independent , Own , When we modify one , Does not affect the value of another
This is the principle of stealing constructor inheritance
2. Implementation method
function Father() {
this.a = [1, 2, 3, 4]
}
function Son() {
Father.call(this)
}
let son1 = new Son()
let son2 = new Son()
son1.a.push(5)
console.log(son1, son2)
Copy code
We can see , In the above implementation , Not directly this.a...
Instead, it adopted Father.call(this)
If you use this.a
Words , Is this also called inheritance ? Is that so?
So using Father.call(this)
What's the reason ?
We originally directly put this.a
Directly written in the subclass function , This is called directly in the subclass Father
The method is similar , The only difference is this
Point to the problem
If it is called directly in the subclass Father()
, So it's this
Will point to window
, In this way, the data cannot be bound to the instance , So we need to change this
The direction of , Point to the current subclass constructor
In this way, the data can be bound to each instance object
At the same time, because our key statement is call
, Therefore, we can pass parameters to the parent class constructor , Pass parameters
3. The problem is
From the implementation code above , I believe you can see , I deliberately ignored the operation of the prototype , No method was added to the prototype of the parent constructor , And this is the problem of this method
Father.prototype.say = function () {
console.log(111);
}
Copy code
Cannot find on subclass say
Method
4. Advantages and disadvantages
advantage :
- Solved the problem that reference values cannot be shared
- Can pass parameters
shortcoming :
- Only instance properties and methods of the parent class can be inherited , Cannot inherit from the parent class Prototype Properties and methods
- The parent method cannot be reused . Every time a subclass is instantiated , To execute the parent function . Redeclare the method defined by the parent class , Cannot reuse .
3、 ... and 、 Combination inheritance
In the first two methods , There are certain defects , So they are rarely used alone . Therefore, a new way of inheritance was born : Combination inheritance ( Pseudo classical inheritance ), Composite inheritance combines the prototype chain with the method of stealing constructor inheritance , Combine the advantages of both .
1. The basic idea
Inherit the properties and methods on the parent class prototype through prototype chain inheritance , Then inherit the properties on the instance by stealing the constructor
such , The method is defined on the prototype to realize reuse , It also ensures that each instance has its own properties
2. Implementation method
Combine the two methods with
function Father() {
this.a = [1, 2, 3, 4]
}
Father.prototype.say = function () {
console.log(111);
}
function Son() {
Father.call(this)
}
Son.prototype = new Father()
let son1 = new Son()
let son2 = new Son()
Copy code
In fact, it just adds the key code inherited by the prototype chain on the basis of stealing the constructor
Son.prototype = new Father()
Copy code
In the code above , Inherits the properties on the parent class instance by stealing the constructor method a
, By way of prototype chain , The prototype object that inherits the parent class
The specific process is only a combination of two , You can turn to the previous explanation
3. The problem is
First, let's print son1 and son2
This result is output , We found that there is also an attribute on its prototype object a
, But this seems to be the initial value , Let's think about why ?
We will Father
The instance of is bound to Son
On the prototype of , But we steal the constructor method
take Father
Its own properties were manually added to Son
The body of , So in Son
On the instantiated object , There will be one. a
attribute , There will also be one on the prototype a
attribute
What problems will this cause ?
Before I answer that question , Let's first count the number of calls Father
Constructors ,
- stay
new
When - stay
call
When
Therefore, on the one hand, there will be some performance problems , Another aspect is that there will be 2 Attributes
4. Advantages and disadvantages
advantage :
- Solve the problem that attributes are shared in prototype chain inheritance
- Solve the problem of borrowing constructor to solve the problem that cannot inherit the parent class prototype object
shortcoming :
- Called the parent function twice , Performance issues
- Due to two calls , It will cause the instance and prototype to have the same properties or methods
Four 、 Original pattern inheritance
I can't seem to find the meaning of this way of inheritance , I don't know what problem it solves with composite patterns ?
1. The basic idea
The idea of prototype inheritance implementation is : Assign the object directly to the prototype of the constructor
2. Implementation method
function object(obj) {
function F(){};
// Assign an object to the prototype of the constructor
F.prototype = obj;
// return new New objects created during
return new F();
}
Copy code
This object
Function creates a temporary constructor , Assign the passed in object to the prototype of the constructor , Then return an instance of the temporary constructor
How can we use it
let student = {name:'xxx'}
let another = object(student)
Copy code
We need to prepare a parent object first , That is, the object to be inherited , Then pass in as a parameter object
function , The returned object is an object that takes the parent object as the prototype object
3. The problem is
In fact, its problems are the same as those of prototype chain inheritance , Properties and methods are shared
let student = {name:['ljc']}
let one = object(student)
let two = object(student)
one.name.push('aaa')
two.name.push('bbb')
Copy code
We give one,two
Object name
Add attributes to the array , Print it again one.name
This creates the problem of being shared
4. Advantages and disadvantages
advantage :
- Compatibility is good. , Simple
- You don't need to create constructors alone
shortcoming :
- Multiple instances share inherited properties , There is a situation that has been tampered with
- Can't pass parameters
ES5
The addition ofObject.create()
Methods , Can replace the aboveobject
Method . It also provides a specification for prototype inheritance
5、 ... and 、 Parasitic inheritance
1. The basic idea
Creates a function that simply encapsulates the inheritance process , The function has some way to enhance the object internally , Finally return the object .
That is, on the basis of prototype inheritance Strengthen the object .
2. Implementation method
function createAnother(original) {
let clone = object(original); // Inherit an object Return new function
clone.sayHi = function () {
console.log('hi');
};
return clone; // Return this object
}
Copy code
In this code , It seems that only on the basis of the original object , Added a method to the object , And encapsulated into a function , For our direct use
3. Advantages and disadvantages
advantage :
- Just focus on the object itself , Don't care about types and constructors
shortcoming :
- Functions are difficult to reuse
- Multiple instances share inherited properties , There is a situation that has been tampered with
- Cannot pass parameter
6、 ... and 、 Parasitic combination inheritance
Combinatorial inheritance still has the problem of efficiency , The main problem is , The parent constructor is always called 2 Time
1. The basic idea
Combine composite inheritance and parasitic inheritance to reduce the number of calls to the parent class , So as to achieve the goal
2. Implementation method
In the method of combinatorial inheritance, we call
Once , also new
Once , Causes the call to 2 Secondary parent class , And in parasitic inheritance , We can call API To implement the prototype of inheriting the parent class
We combine the two
No longer use new
Keywords to change the prototype
function Father() {
this.a = [1, 2, 3, 4]
}
Father.prototype.say = function () {
console.log(111);
}
function Son() {
Father.call(this)
}
Son.prototype = Object.create(Father)
let son1 = new Son()
let son2 = new Son()
Copy code
use Object.create
To override the prototype of a subclass , This reduces calls to the parent class
At this time, we print on the console son1
You will find that the problem has been solved
3. The problem is
In this way , There are also some problems , When there are methods on our subclass prototype
These methods will be lost because the prototype is rewritten
Let's add a... At the top of the code sayHi
Method
Son.prototype.sayHi = function() {
console.log('Hi')
}
Copy code
To solve this problem , In fact, it can be in After the prototype is rewritten Then add the method of subclass prototype
4. Advantages and disadvantages
advantage :
-
It's basically the best inheritance scheme , And, of course, the Grail inheritance
-
The parent constructor was called only once , Save performance .
-
Avoid generating unnecessary attributes
shortcoming :
- Subclass prototypes are overridden
That's what I'm talking about ES5 Medium 6 There are two ways of inheritance
ES6 Inheritance in
because ES6 Previous inheritance was too complex , Too much code , Again ES6 A new inheritance method is introduced in extends
Inherit
use extends
Keyword to implement inheritance
class Father {}
class Son extends Father {
constructor() {
super()
}
}
Copy code
In this way, the subclass inherits the parent class , The key here is to be in the subclass constructor
Add a super
keyword
It should be noted that
In subclass constructor
Must be referenced in method super
Method , Otherwise, the new instance will report an error , This is because of the subclass itself this
object , must Through the first The parent constructor completes the plasticity , Get the properties and methods of the parent class
Then add the subclass's own properties and methods
without super
Method , Subclasses don't have this
object , You're going to report a mistake
About class There's a lot more , Not much here
reference
《JavaScript Advanced programming 》
《JavaScript There are eight common inheritance schemes 》
That's about JS Implementing inherited 7 There's a way , Of course, there are other inheritance methods , The Grail pattern inherits , Copy, inheritance and so on
That's all of this , I hope you like , If you have any questions, you can leave a message in the comment area ~
copyright notice
author[Xiao Cheng],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2021/08/20210827084141580s.html
The sidebar is recommended
- Crazy blessing! Tencent boss's "million JVM learning notes", real topic of Huawei Java interview 2020-2021
- JS JavaScript how to get the subscript of a value in the array
- How to implement injection in vuex source code?
- JQuery operation select (value, setting, selected)
- One line of code teaches you how to advertise on Tanabata Valentine's Day - Animation 3D photo album (music + text) HTML + CSS + JavaScript
- An article disassembles the pyramid architecture behind the gamefi outbreak
- BEM - a front-end CSS naming methodology
- [vue3] encapsulate custom global plug-ins
- Error using swiper plug-in in Vue
- Another ruthless character fell by 40000, which was "more beautiful" than Passat and maiteng, and didn't lose BMW
guess what you like
-
Huang Lei basks in Zhang Yixing's album, and the relationship between teachers and apprentices is no less than that in the past. Netizens envy Huang Lei
-
He was cheated by Wang Xiaofei and Li Chengxuan successively. Is an Yixuan a blessed daughter and not a blessed home?
-
Zhou Shen sang the theme song of the film "summer friends and sunny days" in mainland China. Netizen: endless aftertaste
-
Pink is Wangyuan online! Back to the peak! The new hairstyle is creamy and sassy
-
Front end interview daily 3 + 1 - day 858
-
Spring Webflux tutorial: how to build reactive web applications
-
[golang] walk into go language lesson 24 TCP high-level operation
-
August 23, 2021 Daily: less than three years after its establishment, Google dissolved the health department
-
The female doctor of Southeast University is no less beautiful than the female star. She has been married four times, and her personal experience has been controversial
-
There are many potential safety hazards in Chinese restaurant. The top of the program recording shed collapses, and the artist will fall down if he is careless
Random recommended
- Anti Mafia storm: He Yun's helpless son, Sun Xing, is destined to be caught by his dry son
- Introduction to flex flexible layout in CSS -- learning notes
- CSS learning notes - Flex layout (Ruan Yifeng tutorial summary)
- Today, let's talk about the arrow function of ES6
- Some thoughts on small program development
- Talk about mobile terminal adaptation
- Unwilling to cooperate with Wang Yibo again, Zhao Liying's fans went on a collective strike and made a public apology in less than a day
- JS function scope, closure, let, const
- Zheng Shuang's 30th birthday is deserted. Chen Jia has been sending blessings for ten years. Is it really just forgetting to make friends?
- Unveil the mystery of ascension
- Asynchronous solution async await
- Analysis and expansion of Vue infinite scroll source code
- Compression webpack plugin first screen loading optimization
- Specific usage of vue3 video play plug-in
- "The story of huiyeji" -- people are always greedy, and fairies should be spotless!
- Installing Vue devtool for chrome and Firefox
- Basic usage of JS object
- 1. JavaScript variable promotion mechanism
- Two easy-to-use animation JS that make the page move
- Front end Engineering - scaffold
- Java SQL Server intelligent fixed asset management, back end + front end + mobile end
- Mediator pattern of JavaScript Design Pattern
- Array de duplication problem solution - Nan recognition problem
- New choice for app development: building mobile applications using Vue native
- New gs8 Chengdu auto show announces interior Toyota technology blessing
- Vieira officially terminated his contract and left the team. The national security club sent blessings to him
- Less than 200000 to buy a Ford RV? 2.0T gasoline / diesel power, horizontal bed / longitudinal bed layout can be selected
- How does "heart 4" come to an end? Pinhole was boycotted by the brand, Ma Dong deleted the bad comments, and no one blessed him
- We are fearless in epidemic prevention and control -- pay tribute to the front-line workers of epidemic prevention!
- Front end, netty framework tutorial
- Xiaomi 11 | miui12.5 | android11 solves the problem that the httpcanary certificate cannot be installed
- The wireless charging of SAIC Roewe rx5 plus is so easy to use!
- Upload and preview pictures with JavaScript, and summarize the most complete mybatis core configuration file
- [25] typescript
- CSS transform Complete Guide (Second Edition) flight.archives 007
- Ajax foundation - HTTP foundation of interview essential knowledge
- Cloud lesson | explain in detail how Huawei cloud exclusive load balancing charges
- Decorator pattern of JavaScript Design Pattern
- [JS] 10. Closure application (loop processing)
- Left hand IRR, right hand NPV, master the password of getting rich