When using Javascript, people are often confused by this guy. For most developers with OOP development experience, this is an identifier that references ordinary elements in the current scope, but in Javascript it seems quirky because it is not fixed, but changes as its execution environment changes. In Javascript this always points to the object that calls the method it is located.
Let's give a simple example:
The code copy is as follows:
function test(){
alert(this);
}
var obj=function(){
var name='testObj';
}
obj.objTest=test;
test();
obj.objTest();
Put this code into HTML and run this page, you will see a warning [object window] first, and then a warning.
The code copy is as follows:
var obj=function(){
var name='testObj';
}
We first define a test() method, call the alert() method inside the method to display this, then define an obj function object, add a private field name to it, and add a static method objTest() to it, and this function directly points to the test() function.
The test() and obj.objTest() methods are called respectively. The first warning box prompts the Window object, and the second prompt is the code of the obj function we defined. This shows that the value of this is different when the test function is executed twice!
This shows that when the object calling the function is different, the object referred to by the this keyword inside is different. It should be noted here that Javascript is an object-based language. When our variable or function definition is at the root of the <script></script> tag, it is actually equivalent to adding corresponding properties or methods to the window object. Therefore, when we use function test(){} code to define a function, it is actually equivalent to adding a new function to the window object, namely the window.test() function.
We can do an experiment:
The code copy is as follows:
function test(){
alert(this);
}
alert(test===window.test);
The warning box prompts true, which means that when we call the test() function, it is equivalent to calling window.test(). So when we call the test() function, the object that calls this function is actually a window object, this refers to a window object, so the content of the warning window we pop up when alert(this) is [object Window]. We point obj.objTest=test to point obj.objTest() to test(), so when we call obj.objTest() function, it is equivalent to calling the test() function in obj. So now this refers to the obj object, and the prompt is the obj function, which is the code we see.
Speaking of this, it should be almost the same. Perhaps the above example is too abstract and I can't imagine what circumstances it can be used. So let's assume a requirement and make an example that is closer to practical.
Suppose that all the hyperlinks in our page now need to be changed to red after clicking, and implement them in Javascript. The general idea should be to get all the <a> tags in the page, then iterate through all the <a> tags, register a click event for each one, and after the event is triggered, we set its color value to red.
The sample code is as follows:
The code copy is as follows:
//Change the color
function changeColor(){
this.style.color='#f00';
}
//Initialize, register events for all a tags
function init(){
var customLinks=document.getElementsByTagName('a');
for(i in customLinks){
//You can also use event listener to register events
//Because it may require more code to be compatible with IE, FF and other browsers, you can write it yourself
customLinks[i].onclick=changeColor;
}
}
window.onload=init;
Add this code to the HTML document and add some hyperlinks to the document. When the hyperlink is clicked, the color will turn red. The changeColor() function we defined here refers to the current hyperlink when clicking on the hyperlink. If you call the changeColor() function directly, the browser will report an error, and the error is prompted: 'this.style' is null or not an object or undefined.
I wonder if this can make you, who are reading the article, have some understanding of this keyword in Javascript? Or are you already impatient? (:P)
In fact, in order to truly have a deeper understanding of this issue, you must have a deeper understanding of the scope and scope chain of Javascript.
Scope, as the name suggests, refers to the code space where a certain attribute or method has access rights. Simply put, it is the scope of application of this variable or method in the code. Among most OOPs, there are three scopes: public, private, and protect. I will not explain in detail here. If you have experience in OOP, you should have a deep understanding. What I want to say here is that these three scope types are almost meaningless to Javascript, because there is only one public scope in Javascript, in which scope is maintained in functions. For example:
The code copy is as follows:
var test1='glable variable';
function example(){
var test2='example variable';
alert(test1);
alert(test2);
}
example();
alert(test1);
alert(test2);
According to what we explained earlier, the test1 variable here is equivalent to a property of the window, so it will work within the entire window scope, while test2 is declared internally in the example() function, so its scope is maintained inside the example() method. If the test2 browser is called outside the function, an error will be prompted. And calling test1 inside example() is fine.
Based on this, let's give another example:
The code copy is as follows:
var test='glable variable';
function example(){
var test='example variable';
}
example();
alert(test);
What will happen if this example runs? Yes, the warning box will prompt "glable variable", because the scope of the test variable inside the example() function is only maintained internally and will not affect the external test variable. What if we remove the var keyword of the test variable inside example()? You can try it yourself.
Speaking of this, there is another concept involved, that is, the concept of scope chain. The scope chain is the path that can determine the value of a variable. As can be seen from the above example, the var keyword is used to maintain the scope chain. If the variable uses the var keyword declaration, it can be regarded as the end point of the scope chain. The definition of formal parameters of the same function will also play a similar role.
Speaking of this, you have a clearer understanding of this weird guy, right? According to its simple interpretation, this always points to the object that calls the function it is located. According to the scope and scope chain, we will clearly determine the true face of this. At the end, let’s take a simple change from the beginning of the example:
The code copy is as follows:
function test(){
alert(this);
}
var obj=function(){
var name='testObj';
}
obj.objTest=test;
obj.objTest2=function(){
test();
}
test();
obj.objTest();
obj.objTest2();
What do you guess will prompt? You can try running (:P);
Since this is changed according to the change of the object that calls the function it is in, can we force the change of its calling object? The answer is yes. In future articles, we will introduce this part of the content, as well as the implementation methods of different types of data members in Javascript, closures and other concepts.
I have written some of my experiences and experiences during the learning process. First, I can share them with you and also examine my own shortcomings. If I have any questions about writing, please criticize and give me advice. Thank you very much!