初学者 - 明确这个绑定JavaScript

qar*_*dso 0 javascript binding this

我目前正在读第2章你不知道JS:这和对象原型.

假设我们有这个代码:

function foo() {
    console.log(this.a);
}

var obj = {
    a: 33,
    foo: foo
}

var a = 22;
Run Code Online (Sandbox Code Playgroud)

我理解隐含这种约束:

obj.foo(); // 33
Run Code Online (Sandbox Code Playgroud)

我甚至理解如何使用它作为回调函数使它"失去"它的this价值:

setTimeout(obj.foo, 1000); // undefined
Run Code Online (Sandbox Code Playgroud)

明白的是以下关于使用和的显式绑定的摘录:call()apply()

不幸的是,单独的显式绑定仍然没有为前面提到的问题提供任何解决方案,一个函数"丢失"它的预期绑定,或者只是让它由框架等铺平.

我不明白为什么使用call()(显式绑定)仍然无法解决此问题.

我尝试使用以下示例重新创建它不起作用但似乎setTimeout无法处理使用call()?它会立即触发而不是等待1000毫秒.

setTimeout(foo.call(obj),1000);
Run Code Online (Sandbox Code Playgroud)

我确实意识到使用setTimeout(foo.bind(obj),1000);会解决这个问题,我只是试图理解这本摘自本书的内容.

Fel*_*ing 8

它会立即触发而不是等待1000毫秒

对,因为.call执行功能.也许这更容易理解:foo.call(obj)完全相同obj.foo().但是,setTimeout期望传递一个函数.这就是你做的原因

setTimeout(obj.foo, 1000); 
Run Code Online (Sandbox Code Playgroud)

早些时候,而不是

setTimeout(obj.foo(), 1000); 
Run Code Online (Sandbox Code Playgroud)

那么,如果你不能使用.call,你如何设置this价值?这就是.bind解决的问题.它不是调用函数,而是创建一个带有绑定this值的新函数,然后可以传递这个新函数而不会丢失它的this值.

相关:如何在回调中访问正确的`this`上下文?


这可能不是最准确的概述,但可能有助于理解如何相互关联.call/.apply.bind相互关联:

                    +-------------------+-------------------+
                    |                   |                   |
                    |      time of      |      time of      |
                    |function execution |   this binding    |
                    |                   |                   |
+-------------------+-------------------+-------------------+
|                   |                   |                   |
|  function object  |      future       |      future       |
|         f         |                   |                   |
|                   |                   |                   |
+-------------------+-------------------+-------------------+
|                   |                   |                   |
|   function call   |        now        |        now        |
|        f()        |                   |                   |
|                   |                   |                   |
+-------------------+-------------------+-------------------+
|                   |                   |                   |
|     f.call()      |        now        |        now        |
|     f.apply()     |                   |                   |
|                   |                   |                   |
+-------------------+-------------------+-------------------+
|                   |                   |                   |
|     f.bind()      |      future       |        now        |
|                   |                   |                   |
+-------------------+-------------------+-------------------+
Run Code Online (Sandbox Code Playgroud)