This in js is an old topic. This article is probably the most comprehensive interpretation of this. Take a closer look.
1. First of all, we should understand the concept of objects in js. We say that js objects are roughly divided into dom objects and bom objects, that is, html pages are called objects, browsers are called objects, and the objects created in js are also called objects.
In fact, in the process of daily programming, we may not have established objects. When writing code, we may thank more than n variables and write more than n methods, and the program can run normally.
So you say, I'm useless, too? In fact, all the variables and methods you write are saved in the window object. Window is a browser's global object, such as
var a=1; console.log(a);//1 console.log(window.a);//1
The execution result is 1. In fact, this variable a is regarded as an attribute of the window object. Another example:
function fun(){ console.log(1); } fun();//1 window.fun();//1
All the methods and functions you write are actually a function inside the window object.
So the question comes. After talking for so long, what does it have to do with this? This means "this" in English. Let's use this to refer to the above two codes.
var a=1; console.log(a);//1 console.log(this.a);//1 function fun(){ console.log(1); } fun();//1 this.fun();//1
You can see that in this code, I no longer use the window object, but directly use this. I can also type four 1s. The same effect, so we know that when there is no object outside your variables and functions, that is, the variables and methods you write under normal circumstances
When exposed to window objects, this refers to window. Of course, this is for the native js. In mvvm frameworks such as vue and wechat applets, this point to undefined.
2. Now the scene has changed. We have written an object with certain methods and variables, such as:
var student={ name:"Zhang San", age:24, sayhello:function(){ console.log('I am'+name,'this year'+age+'year'); } } student.sayhello();
The function name () can't be accessed because it's an internal variable. Why can't we know that the function name () can't be accessed? Yes, it's just not accessible.
How can I visit? It's very simple. Add this and write like this:
var student={ name:'Zhang San', age:24, sayhello:function(){ console.log('I am'+this.name,'this year'+this.age+'year'); console.log(this); } } student.sayhello();
No problem. If it can be implemented, we have to think about a question. Who does this represent here? We might as well print him out
An object, student, is printed out. So we can conclude that when this is used inside an object, this points to the object itself. In this example, we create our own objects. In fact, if it is other objects, the reason is the same, such as now
Is a dom object
<html> <head> </head> <body > <div style="width:200px;height:200px" id="bd"></div> <button onclick="press()">Press me div Turn red</button> <script type="text/javascript"> function press() { document.getElementById('bd').style.backgroundColor='red'; console.log(this);//window } </script> </body> </html>
3. In the above code, there is only one function in js without a new object. The object calling this function is the button tag, which belongs to the window object, so the print result must be window;
4. As for the use of this in the callback function, this in the callback function is a special case. It is not satisfied with the theory mentioned above. Suppose there is such a scenario:
var student={ name:'Zhang San', age:24, $.ajax({ type:'GET', url:url, success:function(res){ this.name=res.a; this.age=res.b; console.log(this); }) } }
In an object, there are several attributes, then asynchronous requests, and a callback function. Now I want the values a and B brought back from the callback function to be assigned to the established attributes name and age in the object, and I also want to check who this points to at this time
According to the previous theory, there is no doubt that this can be done. Both name and age can get values. This should refer to the current object, but practice has proved that not only name and age can not get their due values
This does not point to the current object either. Print this and you will find that the result is undefined, which is also a common problem in vue framework, including wechat applet.
First of all, the reason is why this does not point to the current object. This also needs to start with the event loop mechanism of js. Asynchronous functions are usually executed after the execution of synchronous tasks is completed in the method stack. Therefore, the contents in the stack after its execution is completed
It will refresh again. At this time, the callback function has been separated from its object, so it doesn't know where to point to, so it is undefined.
So how to solve this problem. There are two methods. The first is to copy an object this before the callback function is executed, and then let it continue to use this after it is finished. Write it like this:
var student={ var _this=this; name:'Zhang San', age:24, $.ajax({ type:'GET', url:url, success:function(res){ _this.name=res.a; _this.age=res.b; console.log(_this); }) } }
In this way, the callback function can find its own object and complete the data transfer.
The second way is to use the arrow function of ES6. The arrow function is different from ordinary functions. Its this points to the object where it is defined, not the object where it is executed
In this way, when you execute an asynchronous function, you only care about the location of the asynchronous function definition after the execution is completed, so you can use this naturally. The code is as follows:
var student={ name:'Zhang San', age:24, $.ajax({ type:'GET', url:url, success(res)=>{ this.name=res.a;//Use this openly. At this time, this points to the student itself this.age=res.b; console.log(this); }) } }
In fact, the problem that ordinary callback functions cannot obtain this point is a design defect of js. With the many improvements of ES6, the scope division of variables and functions is becoming clearer and clearer. Naturally, this problem does not exist
Therefore, it is recommended that you use ES6 syntax to write code as much as possible.