开发者

Why does `this` change when passing the function argument as string or reference?

Have a look at this:

var a = {
    b: function() {
      console.log(this); 
    }  
}

// Example 1
a.b(); // a

// Example 2    
eval('a.b()'); // a
    
// Example 3
setTimeout('a.b()', 100); // a

// Example 4
setTimeout(a.b, 100); // Window

// Example 5
var c = a.b;
c(); // Window

jsFiddle.

Assuming the expected result is 开发者_开发百科what I expected...

Example 1

When calling b(), the property of an Object, this becomes the property's Object, here it's the parent a. It produces the expected result.

Example 2

eval() is meant to adopt its execution context of where it is called, in this case, window. It also produces the expected result.

Example 3

When passing a string to setTimeout(), I'd imagine it is ran through something very similar to eval(). It too produces the expected result.

Example 4

this becomes Window in this example. This is what I am interested in.

Example 5

Here the this becomes Window, because c's parent object is Window.

  1. When passing only a reference to a function (e.g. a.b), will its this always be Window when called with ()?

  2. Is the only way to keep its this as a to pass it as a string to setTimeout() / setInterval()?


When passing only a reference to a function (e.g. a.b), will its this always be Window when called with ()?

Yes

Is the only way to keep its this as a to pass it as a string to setTimeout() / setInterval()?

No. Create a new function instead.

setTimeout(function() { a.b() }, 100);


Developers are often confused about javascript's this keyword. The most important thing to remember is that it is provided by the call.

In the 4th example:

// Example 4
setTimeout(a.b, 100); // Window

the first argument is a reference to the function, so it's called without any "parent" object. Since the call doesn't provide an object, this is set to window.

Your comment on example 5:

Here the this becomes Window, because c's parent object is Window.

is not really incorrect. Because the function call doesn't provide an object to use as this, it is set to window (which is the default when no object is provided).

Is the only way to keep its this as a to pass it as a string to setTimeout() / setInterval()?

No. Other than calling it as a property of an object, you can use call or apply:

var x = a.b;
x.call(a);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜