JS in the This keyword so many new and old JS developers are confused. This article is a complete description of the This keyword. After reading this article, your confusion will be eliminated. You will learn how to use this correctly in a variety of situations.
We use this in the same way as nouns in natural languages such as English and French. For example, "John runs fast because he wants to catch the train." Please note that the phrase "he" is synonymous with John. We could have expressed that, "John ran as fast as John wanted to catch the train." According to normal language habits, we do not express in the second way. If we speak in the second way, our family and friends will definitely treat us as freaks. Perhaps not only the family, but even our fair and colleagues will be far away from us. Similarly, in JS, we use the This keyword as a shortcut, or as a reference (referent). The This keyword refers to the principal (subject) of the current context (context, which will be interpreted specifically later in this section), or the body of the code block that is currently being executed.
Consider the following code,
1 var person = {2 firstName: "Penelope", 3 lastName: "Barrymore", 4 fullname:function () {5 //As we In the text mentioned using "he" as synonymous with, we use this here 6 7 console.log (This.firstname + "" + this.lastname); 8 //We can actually write this: 9 console.log (Person.firstname + "" + person.lastname); }11 }
If we use Person.firstname and person.lastname, in some cases the code becomes ambiguous. For example, a global variable has a variable name with the same name as a person. In this case, if we want to read the value of the person.firstname, it is possible for the system to read the FirstName property from the person variable of the global variable. This makes it difficult to find errors when we debug the code. So this does not only play a role in beautifying the code, but also to ensure the accuracy of the program. This practice, in fact, is the same as the usage of "he" mentioned earlier, which makes our code clearer. "he" was quoted as "John" at the beginning of the sentence.
Just as the pronoun "he" is used to refer to the antecedent in the sentence (the antecedent is the noun indicated by the pronoun), the This keyword refers to the object that is bound (bound) by the current method (function, which can also be called functions) in the same way. This does not only reference the object, it also contains the value of the object. As with the antecedent, this can also be understood as a shortcut to refer to the current object in context (also known as the "antecedent") (or to moderately reduce the ambiguity of the alternative). We'll be explaining the "context" later.
This Basic theory of keywords
First we need to know that the object has a property set (properties) and that all methods (function) also have a property set. When you run to a method, you have a This property-a variable that stores the value of the object that called the method (which is exactly the method that used the This keyword).
The This keyword always points to an object and holds the value of the object, although it can appear outside the global scope method (function), but it usually appears in the method body. It is important to note that if we use strict mode (strict mode) and the This keyword is used in global functions or anonymous methods that are not bound to any object, this will point to undefined.
This is used in the method body, such as method A, which points to the value of the object that called method A. It is not always possible to find the object name that invokes method A, and this is used to access the methods and properties that are owned by the object that invokes method A. This is really just a shortcut to reference the antecedent-the object that invokes the method.
Let's take a closer look at the following code that uses this.
1 var person = {2 firstName: "Penelope", 3 lastName: "Barrymore", 4 //this used in Showfullname method, and showfullname is defined in the person object, because the object that calls Showfullname is the person, so this has the value of person 5 6 showfullname:function () {7 Console.log (This.firstname + "" + this.lastname); 8 } 9}10 person.showfullname (); Results: Penelope Barrymore
Consider the following example of jquery using this.
1//This is a very simple jquery Code 2 3 $ ("button"). Click (Function (Event) {4 //$ (this) will point to $ ("button") object 5 //Because $ ("button") The object calls the click Method 6 Console.log ($ (this). Prop ("name")); 7});
I would like to elaborate on this jquery example above: The use of $ (this), which is the jquery version of this, which is used in anonymous methods, this anonymous method is executed in the Click event of the button. The reason for this is that $ (this) is bound to the button object because the jquery library binds $ (this) to the object that invokes the click Method. Therefore, although $ (this) is defined in an anonymous method that itself cannot access the "self" variable, $ (this) still points to the button object.
Note that the button is a DOM element of an HTML page and that it is an object: In the example above, because we wrap it in the jquery $ () method, it is a jquery object.
This the core of the keyword
The following rule can help you understand this keyword thoroughly: If a method uses the This keyword internally, the This keyword is only assigned if the object calls the method. We estimate and refer to the method using the This keyword as the "this method".
Although it appears that this refers to the alignment it has in the code, it is not assigned before the method is called, and the value assigned to it is strictly dependent on the object that actually calls the "this method". This is usually given the value of the calling object, and here are some special cases.
This in the global scope
In the global domain, the code executes in the browser, and all variables and methods belong to the Window object. So when we use the This keyword in the global domain, it is pointed to (and owns) the global Variable Window object. As mentioned above, strict mode is excluded. The Window object is the main container for JS a program or a Web page.
Thus:
1 var firstName = "Peter", 2 lastName = "Ally"; 3 4 function Showfullname () {5 ///In this method, this will point to the Window object. Because Showfullname () appears in the global domain. 6 7 console.log (This.firstname + "" + this.lastname); 8} 9 var person = {One firstName: "Penelope", lastName: "Barrymore", showfullname:function () { The following line of code, this points to the person object, because the Showfullname method is called by the person object. Console.log (This.firstname + "" + this.lastname); }17}18 (); The Peter Ally20//window object contains all the global variables and methods, thus the following output will be Window.showfullname (); Peter Ally23 24//The Showfullname method using the This keyword is defined in the Person object, the This keyword points to the person object, as the following output will be Person.showfullname (); Penelope Barrymore
against This a trick .
When the This keyword is used within a method, these situations are most likely to cause misunderstanding: The method is borrowed, the method is assigned to a variable, the method is used as a callback function (callback), and is passed as a parameter; The method that is located is a closure (this method is an internal method). In these cases, we will break each. Before we do this, let's start with a brief introduction to the context.
The context in JS is similar to the subject (subject) In this sentence: "John is the winner and he pays the money". The subject of this sentence is John. We can also say that the context of this sentence is John, because we are concerned about John in this sentence, even if there is a "he" word to refer to the antecedent of John. As we can use a semicolon to toggle the subject of a sentence, the current context object can also be toggled by using a different object to invoke the method.
Similarly, the following JS code:
1 var person = {2 firstName: "Penelope", 3 lastName: "Barrymore", 4 showfullname:function () {5 //Context 6 Console.log (This.firstname + "" + this.lastname); 7 } 8} 9 10//When using the Person object to invoke Showfullname, the context is the person object//showfullname inside the this point to the Person object Person.showfullname () ; Penelope BARRYMORE13//If we use a different object to call showFullName14 var Anotherperson = {FirstName : "Rohit", lastName: " Khan "17};18 19//We can use the Apply method to explicitly set the value of this-later we'll talk about the Apply method, and//this will point to any object that calls the This method, so there will be the following output 21 Person.showFullName.apply (Anotherperson); Rohit Khan22//So now the context is Anotherperson, because Anotherperson indirectly invokes the Showfullname method of person by using the Apply method
Now we are going to formally discuss the trick of dealing with this keyword, which contains the error and the solution that this is causing.
1. When this is used as a callback function to pass in other methods
The trouble comes when we take a method that uses the This keyword as an argument back to the function. For example:
1//The following is a simple object, we define a ClickHandler method. We want this method to be executed when a button on the page is clicked. 2 var user = {3 data: [{4 name: "T. Woods", 5 age:37 6 }, 7 {8 name: "P. Mickelson", 9 Age : 4310 }],11 clickhandler:function (event) { var randomnum = ((Math.random () * 2 | 0) + 1)-1;//random return 0 or 113 //The following line of code randomly prints the name and age of Console.log (This.data[randomnum].name + "" + This.data[randomnum].age) from the array data. The }16}17//button object was wrapped by jquery's $ method and now becomes a jquery object 19//So the output is undefined because the button object does not have the data property of $ $ ("button"). Click (User.clickhandler); Unable to read undefined property
In the above code, we use User.clickhandler as a callback function to pass in the click event of the $ ("button") object, and this in User.clickhandler no longer points to the user object to go. Who called this method containing this will point to WHO. The object that really calls User.clickhandler is the button object-user.clickhandler is executed in the click Method of the Button object.
Attention Although we use User.clickhandler to invoke the Clickhander method (which we can only do because ClickHandler is defined on the user object), the ClickHandler method itself is called by the context object to which this is now directed. So this is now pointing to the $ ("button") object.
When the context changes-when we execute a method on another object rather than on the original object, it is obvious that the this keyword no longer points to the original object that defines the This keyword.
Solution:
Since we really want This.data to point to the data property of the user object, we can use methods such as bind/apply/call to force changes to the object pointed to by this. Other contents in this series will be dedicated to Bind/apply/call, which describes how to force the value of this in different situations. Rather than discussing it in this article, I strongly recommend that you go straight to the other contents (Translator Note: Release the "Other contents" here later).
To solve the problem in the previous code, we can use the Bind method.
For the following line of code:
$ ("button"). Click (User.clickhandler);
We can bind the ClickHandler user object with the Bind method:
$ ("button"). Click (user.clickHandler.bind (user)); P. Mickelson 43
2. This in the closure
The use of this in internal methods, or closures, is another example that can easily be misunderstood. We must note that the internal method cannot access the this variable of the external method directly by using the This keyword, because the this variable can only be used by the specific method itself. For example:
1 var user = {2 tournament: "The Masters", 3 data: [{4 name: "T. Woods", 5 age:37 6 }, 7 {8
name: "P. Mickelson", 9 age:4310 }],11 clickhandler:function () { // There is not much problem in using this.data because this is pointing to the user object, and data is a property of user This.data.forEach (person) { However, in this anonymous method (which is passed as a parameter to the Foreach method), this no longer points to the user object, the this17 Console.log of the internal method cannot access the external method. Referring to? "+ this); The output is: [Object window]18 Console.log (Person.name + "was playing at" + this.tournament); + /T. Woods is Playi ng at UNDEFINED20 //P. Mickelson are playing at Undefined21 }),}23 (}25) User.clickhandler (); What is the "this" referring? [Object Window]
Because this in an anonymous method cannot access this of an external method, in non-strict mode, this points to the global window object
Solution:
An additional variable is used to refer to this before entering the Foreach method.
1 var user = {2 tournament: "The Masters", 3 data: [{4 name: "T. Woods", 5 age:37 6 }, 7 {8
name: "P. Mickelson", 9 age:4310 }],11 clickhandler:function (event) { // To capture the value of this pointer to the user object, we assign it to another variable theuserobj, which we can use theUserObj14 var theuserobj = this;15 This.data.forEach (person) { ///Now we don't have to this.tournament, we use theuserobj.tournament17 Console.log (Person.name + "is playing at" + theuserobj.tournament); (}20)}22 (+ user.clickhandler) ; 2 4//T. Woods is playing at the MASTERS25//P. Mickelson are playing at the Masters
As the following code, many JS developers like to use the variable that to set the value of this. But I personally do not like to use that name, I like the use of a person can be a glance to understand who is the name of this point, so the above code I used Theuserobj = this.
1//This code is more common to most JS developers than the 2 var = this;
3. Method is assigned to a variable
This keyword is sometimes very naughty, if we assign a method that uses the This keyword to a variable, let's see what interesting things happen:
1//Data variable is a global variable 2 var data = [{3 Name: "Samantha", 4 age:12 5}, 6 {7 name: "Alexis", 8 age:14 9}] ; var user = { ///And the data here is a property of user : [{ ] "T. Woods", age:3716 },17 {18< C10/>name: "P. Mickelson", age:4320 }],21 showdata:function (event) {$ var randomnum = (( Math.random () * 2 | 0) + 1)-1; Randomly generated 1 or 023 //This sentence will randomly display the name and age of Console.log (This.data[randomnum].name + "" + This.data[randomnum) from the array data. age); }26 27}28 29//Assign User.showdata method to variable showUserData30 var showuserdata = user.showdata;31 32//Execute Showuserdata method, the result will be from the global data array rather than the data property of the User object, Showuserdata (); Samantha 12 (from global variable data) 34//solution: Explicitly set the value of this by using the Bind method 35//Bind the ShowData method to the user object on the var showuserdata = User.showData.bind (user); 37 38//The result will now come from the user object because the This keyword has been forcibly bound to the user object on the Showuserdata (); P. Mickelson 43
4. Problems arising from borrowing methods
In JS development, the Borrowing method (borrowing methods) is very common. For borrowing methods, refer to the other contents in this series.
Let's look at the following code:
1//The code below has two objects. One defines the Avg method, and the other does not contain the definition of Avg. We use another object to borrow the Avg method of the previous object. 2 var gamecontroller = {3 scores: [], 4 avgscore:null, 5 players: [{6], [+], [+], [+]] 7 playerid:987, 8 age:23 9 },10 {One name: "Pau", playerid:87,13 age:3314 }]15 }16 var AppController = { scores: [845, 809, 950],19 avgscore:null,20 avg:function () {22
var sumofscores = this.scores.reduce (function (prev, cur, index, array) {prev + cur;24 }); >this.avgscore = sumofscores/this.scores.length;27 }28}29 30//If the following code is executed, The actual value of the Gamecontroller.avgscore property will be taken from the scores of AppController 31//Do not execute the following code, we just want to explain this situation. In fact, we want to make appcontroller.avgscore still null. Gamecontroller.avgscore = Appcontroller.avg ();
The This keyword of the Avg method points to the Gamecontroller object, and if this method is called with AppController, this will point to AppController (but in fact this is not the result we expect, Because we just want to borrow the implementation logic of the method rather than the specific data source.
Solution:
To ensure that Gamecontroller only borrows the logic of the AppController Avg method, we use the Apply method:
1//We want to use the Apply method, note here the second parameter of the incoming Appcontroller.avg Method 2 appController.avg.apply (Gamecontroller, gamecontroller.scores); 3 4//Although the Avg method is borrowed, now the Avgscore attribute has been successfully applied to the Gamecontroller. 5 Console.log (Gamecontroller.avgscore); 46.46//appcontroller.avgscore is still null, only Gamecontroller's Avgscore was updated by 7 Console.log (Appcontroller.avgscore); Null
Gamecontroller only borrowed the Avg method of AppController, and this will point to Gamecontroller because we pass the Gamecontroller as the first parameter of the Apply method. The first parameter of the Apply method will explicitly set the value of this.
Conclusion
I hope you have something to gain in the article. Now you can use the trick described in the article (bind method, apply method, call method, and assign this to a variable) to deal with any problems associated with this.
As already understood, this will always point to the object that invokes the current method when the context changes, is used as a callback function, is called by a different object, or the method is borrowed.
This keyword is detailed