为什么在将函数参数作为字符串或引用传递时,`this`会发生变化?

时间:2021-08-07 18:47:37

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.

当调用对象的属性b()时,它成为属性的对象,这里是父对象。它产生预期的结果。

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.

eval()意味着采用它的调用位置的执行上下文,在本例中是window。它还产生预期的结果。

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.

将字符串传递给setTimeout()时,我想它会遇到与eval()非常相似的东西。它也产生预期的结果。

Example 4

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

在这个例子中,这变成了Window。这就是我感兴趣的。

Example 5

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

这里变成了Window,因为c的父对象是Window。

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

    当只传递一个函数的引用(例如a.b)时,用()调用它时它总是Window吗?

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

    唯一的方法是将它作为一个字符串传递给setTimeout()/ setInterval()吗?

2 个解决方案

#1


7  

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

当只传递一个函数的引用(例如a.b)时,用()调用它时它总是Window吗?

Yes

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

唯一的方法是将它作为一个字符串传递给setTimeout()/ setInterval()吗?

No. Create a new function instead.

不。而是创建一个新功能。

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

#2


1  

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

开发人员经常对javascript这个关键字感到困惑。最重要的是要记住它是由呼叫提供的。

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.

第一个参数是对函数的引用,因此在没有任何“父”对象的情况下调用它。由于调用不提供对象,因此将其设置为window。

Your comment on example 5:

您对示例5的评论:

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

这里变成了Window,因为c的父对象是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).

是不是真的不对。因为函数调用不提供要用作此对象的对象,所以它被设置为window(这是没有提供对象时的默认值)。

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

唯一的方法是将它作为一个字符串传递给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);

#1


7  

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

当只传递一个函数的引用(例如a.b)时,用()调用它时它总是Window吗?

Yes

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

唯一的方法是将它作为一个字符串传递给setTimeout()/ setInterval()吗?

No. Create a new function instead.

不。而是创建一个新功能。

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

#2


1  

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

开发人员经常对javascript这个关键字感到困惑。最重要的是要记住它是由呼叫提供的。

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.

第一个参数是对函数的引用,因此在没有任何“父”对象的情况下调用它。由于调用不提供对象,因此将其设置为window。

Your comment on example 5:

您对示例5的评论:

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

这里变成了Window,因为c的父对象是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).

是不是真的不对。因为函数调用不提供要用作此对象的对象,所以它被设置为window(这是没有提供对象时的默认值)。

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

唯一的方法是将它作为一个字符串传递给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);