In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly explains "how to understand and master the this keyword in JavaScript". The content in the article is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "how to understand and master the this keyword in JavaScript".
This in JavaScript
The JavaScript engine does not go through the prototype chain layer by layer when looking for this, because this can only be determined at the time of function calls, so let's look at the following forms of function calls.
1. Function Invocation Pattern
A normal function call, which we use more often, foo appears as a separate variable rather than a property. Where the this points to the global object.
Function foo () {console.log (this)} foo () / / Window
The function, as a method call to the object, is called in the form of obj.func or obj [func]. Where the this points to the object that called it.
Const obj = {name: 'lxfriday', getName () {console.log (this.name)}} obj.getName () / / lxfriday
2. Constructor Pattern
Called in the form of new Constructor (), its this points to the newly generated object.
Function Person (name) {this.name = name} const person = new Person ('lxfriday') console.log (person.name) / / lxfriday
3. Apply Pattern
Called in the form of foo.apply (thisObj) or foo.call (thisObj), where this points to thisObj. If thisObj is null or undefined, the this in it points to the global context Window (in the browser).
Mastering the above several function call forms can basically cover the common problems encountered in development. I have translated an article below to help you understand this more deeply.
If you have used some JavaScript libraries, you will surely notice a special keyword this.
This is common in JavaScript, but many developers spend a lot of time fully understanding the exact function of the this keyword and where to use it in the code.
In this article, I'll help you learn more about how this works.
Before delving into it, make sure that Node is installed on your system. Then, open the command terminal and run the node command.
This in the global environment
How this works is not easy to understand. To understand how this works, we will explore this in different environments. Let's start with the global context.
At the global level, this is equivalent to a global object and is called global in an Node repl (interactive command line) environment.
$node > this = global true
But this only happens in the Node repl environment, and if we run the same code in the JS file, we will get a different answer.
To test, we create an index.js file and add the following code:
Console.log (this = global)
Then run it through the node command:
$node index.js false
The reason for this is that in the JS file, this points to module.exports, not to global.
This in function
Function Invocation Pattern
The direction of this in a function depends on the form in which the function is called. Therefore, each time a function executes, it may have a different this point.
In the index.js file, write a very simple function to check whether this points to the global object:
Function fat () {console.log (this = global)} fat ()
If we execute the above code in the Node repl environment, we will get true, but if we add use strict to the first line, we will get false, because at this time the value of this is undefined.
To further illustrate this point, let's create a simple function that defines the real name of the superhero and the name of the hero.
Function Hero (heroName, realName) {this.realName = realName; this.heroName = heroName;} const superman= Hero ("Superman", "Clark Kent"); console.log (superman)
Note that this function is not executed in strict mode. The code running in node will not have the Superman and Clark Kent that we expected, but we will get undefined.
The reason behind this is that because the function is not written in strict mode, this references the global object.
If we run this code in strict mode, there will be an error because JavaScript does not allow attributes to be added to undefined. This is actually a good thing because it prevents us from creating global variables.
Finally, writing the name of the function in uppercase means that we need to call it as a constructor using the new operator. Replace the last two lines of the above code fragment with:
Const superman = new Hero ("Superman", "Clark Kent"); console.log (superman)
Run the node index.js command again, and you will now get the expected output.
This in constructor
Constructor Pattern
JavaScript does not have any special constructors. All we can do is use the new operator to convert the function call to the constructor call, as shown in the previous section.
When you make a constructor call, a new object is created and set as the function's this parameter. Then, the object is returned implicitly from the function unless we have another object to return explicitly.
Write the following return statement inside the hero function:
Return {heroName: "Batman", realName: "Bruce Wayne",}
If we run the node command now, we will see that the return statement will override the constructor call.
When the return statement attempts to return anything that is not an object, it implicitly returns this.
This in the method
Method Invocation Pattern
When a function is called as a method of an object, the this points to the object and then calls the object the receiver of the function call.
In the following code, there is a dialogue method inside the hero object. When called in the form of hero.dialogue (), the this in dialogue points to hero itself. Here, hero is the receiver of the dialogue method call.
Const hero = {heroName: "Batman", dialogue () {console.log (`I am ${this.heroName}! `);}}; hero.dialogue ()
The above code is very simple, but in actual development, it is possible that the receiver of the method call is not the original object. Look at the following code:
Const saying = hero.dialogue (); saying ()
Here, we assign the method to a variable, and then execute the function that the variable points to, and you will find that the value of this is undefined. This is because the dialogue method can no longer track the original recipient object, and the function now points to the global object.
When we pass one method as a callback to another, a loss of the receiver usually occurs. We can solve this problem by adding a wrapper function or by binding the this to a specific object using the bind method.
Call 、 apply
Apply Pattern
Although the this value of the function is implicitly set, we can also explicitly bind this through call () and apply ().
Let's reorganize the previous code snippet like this:
Function dialogue () {console.log (`I am ${this.heroName} `);} const hero = {heroName: 'Batman',}
We need to connect the hero object as a receiver to the dialogue function. To do this, we can use call () or apply () to implement the connection:
Dialogue.call (hero) / / or dialogue.apply (hero)
It should be noted that in non-strict mode, passing null or undefined to call or apply as context will cause this to point to the global object.
Function dialogue () {console.log ('this', this)} const hero = {heroName:' Batman',} console.log (dialogue.call (null))
The above code outputs null in strict mode and global objects in non-strict mode.
Bind
When we pass a method to another function as a callback, there is always a risk of losing the expected recipient of the method, resulting in setting the this parameter to the global object.
The bind () method allows us to permanently bind the this parameter to the function. Therefore, in the following code snippet, bind will create a new dialogue function and set its this value to hero.
Const hero = {heroName: "Batman", dialogue () {console.log (`I am ${this.heroName} `);}}; / / print after 1s: I am Batman setTimeout (hero.dialogue.bind (hero), 1000)
Note: for newly generated functions after binding this with bind, you cannot change the this of this new function using the call or apply methods.
This in Arrow function
The arrow function is very different from the ordinary function, citing the introduction in Chapter 6 of Ruan Yifeng's introduction to ES6:
The this object in the body of a function is the object in which it is defined, not the object in which it is used.
Cannot be treated as a constructor, that is, you cannot use the new command, or an error will be thrown
You cannot use an arguments object, which does not exist in the body of the function. If you want to use it, use the rest parameter instead
The yield command cannot be used, so the arrow function cannot be used as a Generator function
Of the above four points, the first is particularly noteworthy. The direction of the this object is variable, but in the arrow function, it is fixed, it only points to the outer this when the arrow function is defined, the arrow function does not have its own this, and all operations that bind this, such as call apply bind, are invalid to the this binding in the arrow function.
Let's take a look at the following code:
Const batman = this; const bruce = () = > {console.log (this = batman);}; bruce ()
Here, we store the value of this in a variable and compare that value with the this value inside the arrow function. True will be output when node index.js executes.
What can this in the arrow function do?
The arrow function can help us access this in the callback. Take a look at the counter object I wrote below:
Const counter = {count: 0, increase () {setInterval (function () {console.log (+ + this.count);}, 1000);}} counter.increase ()
Run the above code and NaN will be printed. This is because this.count does not point to the counter object. It actually points to the global object.
To make this counter work, you can rewrite it with the arrow function, and the following code will work properly:
Const counter = {count: 0, increase () {setInterval (()) = > {console.log (+ + this.count);}, 1000);},}; counter.increase ()
This in the class
Class is one of the most important parts of all JavaScript applications. Let's look at the behavior of this within the class.
A class usually contains a constructor where the this will point to the newly created object.
However, in the case of a method, if the method is called as an ordinary function, this can also point to any other value. Like a method, a class may not be able to track the recipient.
We rewrite the above Hero function with the class. This class will contain the constructor and the dialogue () method. Finally, we create an instance of this class and call the dialogue method.
Class Hero {constructor (heroName) {this.heroName = heroName;} dialogue () {console.log (`I am ${this.heroName} `)} const batman = new Hero ("Batman"); batman.dialogue ()
The this in constructor points to the newly created class instance. When batman.dialogue () is called, we call dialogue () as the method call of the batman receiver.
However, if we store a reference to the dialogue () method and then call it as a function, we will once again lose the receiver of the method, and this now points to undefined.
Why point to undefined? This is because the JavaScript class implicitly runs in strict mode. We use say () as a function call without binding. So we need to bind manually.
Const say = batman.dialogue.bind (batman); say ()
Of course, we can also bind inside the constructor:
Class Hero {constructor (heroName) {this.heroName = heroName thisthis.dialogue = this.dialogue.bind (this)} dialogue () {console.log (`I am ${this.heroName} `)}}
Extra meal: handwritten call, apply, bind
The simulation implementations of call and apply are more or less the same. Note that the parameters of apply are an array, and the binding this is in the form of object calling methods.
Function.prototype.call = function (thisObj) {thisObjthisObj = thisObj | | window const funcName = Symbol ('func') const that = this / / func thisObj [funcName] = that const result = thisObj [funcName] (. Arguments) delete thisObj [funcName] return result} Function.prototype.apply = function (thisObj) {thisObjthisObj = thisObj | window const funcName = Symbol (' func') const that = this / / func const args = arguments [1] | | [] thisObj [funcName] = that const result = thisObj [funcName] (. [thisObj . args]) delete thisObj [funcName] return result} Function.prototype.bind = function (thisObj) {thisObjthisObj = thisObj | | window const that = this / / func const outerArgs = [. Arguments] .slice (1) return function (. InnerArgs) {return that.apply (thisObj, outerArgs.concat (innerArgs))}} Thank you for reading The above is the content of "how to understand and master the this keyword in JavaScript". After the study of this article, I believe you have a deeper understanding of how to understand and master the this keyword in JavaScript. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.