Some days ago when I practiced writing a small example, I used a timer and found that in SetInterval and settimeout, the this in the function points to the Window object, as in the following example:
varnum = 0;functionObj () { This. num = 1, This. Getnum =function() {Console.log ( This. Num); }, This. Getnumlater =function() {setTimeout (function() {Console.log ( This. Num); }, 1000) }}varobj =NewObj; Obj.getnum ();//1 Printed as Obj.num, with a value of 1Obj.getnumlater ()//0 Printed as Window.num, with a value of 0
From the above example, you can see that this in the function in settimeout is pointing to the Window object, which is due to the setTimeout()调用的代码运行在与所在函数
completely detached execution environment. This causes the keywords contained in these code to this
point to window
(or 全局
) the object. Detailed reference to MDN setTimeout
But when a function is not passed in settimeout, this points to the current object, as in the following example:
varnum = 0;functionObj () { This. num = 1, This. Getnum =function() {Console.log ( This. Num); }, This. Getnumlater =function() {setTimeout (Console.log ( This. Num),1000) }}varobj =NewObj; Obj.getnum ();//1 Printed as Obj.num, with a value of 1Obj.getnumlater ()//1printed as Obj.num, with a value of 1
As can be seen from the above two examples, when the parameter passed in the settimeout is a function, this within the function points to the Window object.
When a function is passed in settimeout, if you want this to point to the correct value, you can use the following two more common methods to point this to the correct value:
1. Save this current object as a variable, and the function within the timer accesses the variable using the closed package as follows:
varnum = 0;functionObj () {varthat = This;//Save this as a variable, at which point this points to obj This. num = 1, This. Getnum =function() {Console.log ( This. Num); }, This. Getnumlater =function() {setTimeout (function() {console.log (that.num); //using closures to access that,that is a pointer to obj}, 1000) }}varobj =NewObj; Obj.getnum ();//1 Printed as Obj.num, with a value of 1Obj.getnumlater ()//1printed as Obj.num, with a value of 1
This method is to put a reference to the current object in a variable, the function of the timer inside to access the variable, you can naturally get the current object.
2. Using the Bind () method
varnum = 0;functionObj () { This. num = 1, This. Getnum =function() {Console.log ( This. Num); }, This. Getnumlater =function() {setTimeout (function() {Console.log ( This. Num); }.bind ( This), 1000)//bind this to this function using bind () }}varobj =NewObj; Obj.getnum ();//1 Printed as Obj.num, with a value of 1Obj.getnumlater ()//1 Printed as Obj.num, with a value of 1
The bind () method is a method on Function.prototype, and when executed by a bound function, the Bind method creates a new function and takes the first argument as the this when the new function is run. In this example, when invoking a function in SetTimeout, the Bind method creates a new function and passes this to the new function, and the result is correct. Refer to MDN bind for bind method
The above two methods are more commonly used, of course, if you use the call or Apply method to replace the Bind method, the result is also correct, but calls method will be executed immediately after the invocation, so there is no delay effect, the timer is useless, Therefore, we recommend using both methods to pass this into settimeout and setinterval.
About the this point problem in SetInterval and settimeout