In depth understanding of the scope of this in Javascript

  • 2020-03-30 03:40:50
  • OfStack

People are often confused by this guy when they use Javascript. To most developers with OOP development experience, this is an identifier that refers to a common element in the current scope, but in Javascript it is tricky because it is not fixed, but changes as its execution environment changes. In Javascript this always points to the object that calls its method.

Here's a simple example:


function test(){
alert(this);
}
var obj=function(){
var name='testObj';
}
obj.objTest=test;
test();
obj.objTest();

If you put this code in HTML and run the page, you'll see an object window warning, and then a second warning.


var obj=function(){
var name='testObj';
}

We first defined a test() method and called the alert() method inside to display this, then defined an obj function object with a private field name and a static method objTest() that points directly to the test() function.

We call the methods test() and obj.objtest (), respectively. The first warning box prompts the Window object, and the second prompts the code of the function we defined, obj. This indicates that the value of this is different when the test function is executed twice!

This means that when the object calling the function is different, the internal this keyword refers to a different object. It is important to note that Javascript is an object based language when our variables or functions are defined in < Script> < / script> The root of the label is actually equivalent to adding the corresponding properties or methods to the window object, so when we use the 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:


function test(){
alert(this);
}
alert(test===window.test);

The warning box will say true, which means that when we call the function test(), we are calling window.test(). So when we call the test() function, the object that calls this function is actually the window object, and this refers to the window object, so the warning window that pops up when we alert(this) is [object window]. So when we call the obj.objTest() Function, we call the test() Function in the obj. So now this refers to the obj object, and the obj Function is the code that we see.

Now, I think that's pretty much explained, and maybe the above example is too abstract to be used in any situation, so let's just assume a requirement and do a practical example.

Suppose that all of the hyperlinks in our current page were to be changed to red after we clicked, using Javascript. The general idea should be to get all of them on the page. A> Tag, and then go through all the < A> Label, register a click event for each, and set its color value to red when the event fires.

The sample code is as follows:


//Change the color
function changeColor(){
this.style.color='#f00';
}
//Class to register events
for all a tags function init(){
var customLinks=document.getElementsByTagName('a');
for(i in customLinks){
//You can also use event listener mode to register events
//Since more code may be required to be compatible with browsers such as IE and FF, you can write
yourself customLinks[i].onclick=changeColor;
}
}
window.onload=init;

Add this code to the HTML document and add some hyperlinks to the document that will turn red when the hyperlink is clicked. The keyword in the changeColor() function we defined here refers to the current hyperlink when the hyperlink is clicked. If you call the changeColor() function directly, the browser will report an Error: 'this.style' is null or not an object or undefined.

I don't know if this will give you some insight into this keyword in Javascript as you read this article. Or are you impatient? (: P)

In fact, in order to really have a deeper understanding of this problem, you have to have a deeper understanding of the scope and the scope chain of Javascript.

Scope, as the name implies, refers to a certain property or method has access to the code space, simply said that the variable or method in the code it is applicable to the scope. In most OOP, there are three main scopes: public, private, and protect. The three scopes are not explained in detail here. If you have OOP experience, you should have a deep understanding. What I'm saying here is that these three scope types are almost meaningless to Javascript, because there is only one common scope in Javascript, and in Javascript the scope is maintained in the function. For example:


var test1='globle variable';
function example(){
var test2='example variable';
alert(test1);
alert(test2);
}
example();
alert(test1);
alert(test2);

As we explained earlier, the test1 variable here corresponds to a property of the window, so it will function in the entire window scope, while test2 is declared inside the example() function, so its scope remains inside the example() method, and an error will occur if the test2 browser is called outside the function. Calling test1 inside example() is fine.

Here's another example from this:


var test='globle variable';
function example(){
var test='example variable';
}
example();
alert(test);

What happens when this example runs? Yes, the warning box prompts "globle variable" because the test variable inside the example() function is only kept inside and does not affect the external test variable. What if we removed the var keyword from the internal test variable example()? You can try it yourself.

And then there's another concept involved, which is the concept of scope chains. A scoped chain is a path that determines the value of a variable. From the above example, we can see that the var keyword is used to maintain the scope chain. If the variable is declared with the var keyword, it can be seen as the end of the scope chain. Similarly, the definition of the parameter of the function will play a similar role.

Speaking of which, do you have a clearer idea of this elvish weirdo? By its simple interpretation, this always points to the object that calls its function, and by its scope and scope chain, we can clearly identify this. At the end, a simple change from the beginning example:


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 think will be suggested? You can try it by running (:P);

Since this is changed according to the object calling its function, can we force it to change its calling object? The answer is yes, and a future article will cover this, as well as the different types of data members implemented in Javascript, closures, and so on.

I am in the process of learning some experience and experience, write out is to share with you in addition also can examine their own shortcomings, if there is a problem also please comment, thank you very much!


Related articles: