Deep understanding of the scope of settimeout

Source: Internet
Author: User

Read a question about the scope of the settimeout, in fact, in the "JavaScript Advanced Programming" also saw, share to you:

First summarize the following:

One, the this in the deferred execution code in settimeout always points to window

Second, SetTimeout (This.method, time) in this form, the first one mentioned above is judged by the context, which defaults to the global scope , but not necessarily always in the global context, specifically analyzing the problem.

Third, setTimeout (anonymous function, time) in this form, the variables in the anonymous function also need to be judged according to the context, and the specific problem is analyzed. In fact, in the anonymous function, if this.value===window.value, if value is the normal variable value in its current scope.

。 We know that the SetTimeout method is hung under the Window object. In the second edition of JavaScript Advanced Programming, it is written that "the code for the timeout call is executed in the global scope, so the value of this in the function points to the window object in non-strict mode and is undefined in strict mode." Here, we only discuss the non-strict mode.

SetTimeout accepts two parameters, the first is the code or function to execute, and the second is the time of the delay.

First, say the conclusion: this in the function executed in settimeout, always points to window!! Note is the this in the function to delay execution Oh!!

1. Direct use, Code 1.1:

SetTimeout ("alert (This)", 1);   [Object Window]

2. Call settimeout in an object, code 1.2:

var obj = {  say:function () {    setTimeout ("alert (' in obj ' + this)", 0)  }}obj.say ();   In obj [Object Window]

3. Replace the executed code with an anonymous function try, code 1.3:

var obj = {  say:function () {    setTimeout (function () {alert (this)}, 0)  }}obj.say ();  [Object Window]

4. Change to a function reference and try it again, code 1.4:

function talk () {  alert (this);} var obj = {  say:function () {    setTimeout (talk, 0)  }}obj.say ();  [Object Window]

Well, it seems that the conclusion is correct, and this in the deferred execution function in settimeout points to the window. Here I repeatedly emphasize that this is the deferred execution function, because we often meet on two this. One is this in the settimeout invocation environment, and the other is the this in the deferred execution function. These two this are sometimes different. Some don't trust?? Write some more code to test it!

Second, settimeout in the two this point to who?? For the sake of distinction, we call this the first this in the SetTimeout invocation environment, this is called the second this in the deferred execution function, and the code comment is made to make it easier for you to distinguish between the two. First, the conclusion: the point of the first this is to be determined by context, the default is window, and the second is to point to window. Then we pass the code to verify the next.

1. If the function is called as a method call or a constructor, this is different. Look at the code first, Code 2.1:

function Foo () {    this.value =;    This.method = function () {        //This points to a global object        alert (this)//   Output Window  second this        alert (this.value); Output: Undefined   second this    };    SetTimeout (This.method,);  This is an instance object that points to foo the  first this}new foo ();

We have a new Foo object, so this is the new object in This.method, otherwise we can't call the method. However, when the method method is entered, the this in the methods points to the window, so the value of this.value is undefined.

We add a piece of code to the outer layer, and then look at the code 2.2:

var value=33;function Foo () {    this.value =;    This.method = function () {        //This points to a global object        alert (this)//   Output Window    second this        alert (this.value); Output:   a second this    };    SetTimeout (This.method,);  Here is the instance object of Foo that points to the  first this}new foo ();

From here, it can be seen clearly that this in the method approach refers to window because the value of the outer layer can be output. So why is this in settimeout pointing to the instance object of Foo?

I think code 2.2 is equivalent to the following code, such as code 2.3:

var value=33;function Foo () {    this.value =;    SetTimeout (function () {alert (this); Alert (This.value)}, +);  Successively Output Window   ,  here is the second this}new Foo ();

The first argument in settimeout is simply a reference to a function, and this in the function still points to window. This in settimeout (This.method, time) can be changed depending on the context, and its ultimate purpose is to get a function pointer. Let's check it out again, see Code 2.4:

Function method () {  alert (this.value);  Output  of the second this}function Foo () {    this.value =;    SetTimeout (This.method,);  Here this one points to window   first This}foo ();

This time we take Foo as a method of direct execution, the method is placed in the outer layer, that is, hanging on the window. This points to the window, so you can call the method methods. This method is still pointing to Window while Foo () executes, and Window.value is assigned (THIS.VALUE=42), so the output is 42.

 

Third, practice. Know the conclusion, we come to read some of the more wonderful code, to verify.

First, in a function, call settimeout. Code Listing 3.1:

var test = "in the window"; SetTimeout (function () {Alert (' outer ' + Test)}, 0); Output outer in the window, default to the global scope of window function f () {  var test = ' in the f! ';  Local variables, window scope inaccessible  setTimeout (' Alert (' inner ' + test) ', 0);  The output outer in the window, although called in the F method, but the execution code (code in string form) defaults to the window global scope, and test also points to the global test}f ();

In the F method, the value of test in settimeout is the outer test, not the test in the F-scope. Look at code 3.2 again:

var test = "in the window"; SetTimeout (function () {Alert (' outer ' + Test)}, 0); Outer in the window  , no problem, in the global downgrade, Access Global testfunction F () {  var test = ' in the f! ';  SetTimeout (function () {alert (' inner ' + Test)}, 0);  Inner in the f!  There's a problem, not a good deal. Does the this in the Execute function point to window? The test should also correspond to the                                                      value of window//, how the value of  test is the value of f ()???? }f ();

Yes. According to the previous experience, the test in settimeout in F should also be the one pointing to the outer layer of test, right??? We notice that the first parameter in the F-settimeout is an anonymous function, which is the biggest difference between the two ends of the code. And as long as the function has its scope, we can replace the above code with the following code 3.3:

var test = "in the window"; SetTimeout (function () {Alert (' outer ' + Test)}, 0); In the windowfunction f () {  var test = ' in the f! ';  function ff () {alert (' inner ' + Test)}//can access the test local variable  setTimeout (FF, 0) in F;  Inner in the f!} f ();

Look at a clearer code, 3.4:

var value=33;function Foo () {    var value =;    SetTimeout (function () {alert (value); alert (This.value)}, +);  Successively output 42 and then output  The This is the second this}new Foo ();

It can be determined that the this in the deferred execution function is indeed pointing to window, without a doubt that all of the above code can be verified by ha. However, the other variables in the deferred execution function need to be validated against the context.

Modifying code 3.4 to 3.5, removing the invocation of anonymous functions will be clearer:

var value=33;function Foo () {    var value =;    function ff () {      alert (value);      alert (this.value);    setTimeout (FF, +);  Successively output  }foo ();//Direct execution, no difference from normal function

So, if you get rid of value=42 in Foo, then what is value equal to? Undefined or the outer 33?? Take a look at 3.5:

var value=33;function Foo () {    function ff () {      alert (value);   Output      alert (this.value);  Output this  point to window    }    setTimeout (FF, +);  Successively output  }foo ();

Yes, that's the outer 33, because FF can access the value under window, just like an anonymous function in settimeout.

Finally, we call the object by the way, code 3.6:

var obj = {  name: ' Hutaoer ',  say:function () {    var = this;    SetTimeout (function () {      alert (self);   Output object, pointing to obj      alert (this);   Second this, point to window, my heart is eternal, never change      alert (self.name)  //Output Hutaoer    }, 0)  }}obj.say ();

Deep understanding of the scope of settimeout

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.