初学者 - 明确这个绑定JavaScript

时间:2016-05-27 15:40:20

标签: javascript binding this

我目前正在阅读你不知道JS的Chapter 2:这个和对象原型

我们说我们有这个代码:

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

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

var a = 22;

我理解隐含这种约束:

obj.foo(); // 33

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

setTimeout(obj.foo, 1000); // undefined

了解以下摘录 Explicit Binding 使用call()apply()

  

不幸的是,单独的显式绑定仍然无法提供任何解决方案   对于前面提到的问题,一个功能"失去"它的意图   这种绑定,或者只是通过框架等来铺平它。

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

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

setTimeout(foo.call(obj),1000);

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

2 个答案:

答案 0 :(得分:6)

  

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

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

setTimeout(obj.foo, 1000); 

早些时候,而不是

setTimeout(obj.foo(), 1000); 

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

相关:How to access the correct `this` context inside a callback?

这可能不是最准确的概述,但可能有助于了解如何将.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        |
|                   |                   |                   |
+-------------------+-------------------+-------------------+

答案 1 :(得分:1)

this的值会根据调用函数的人而改变。

setTimeout(obj.foo, 1000); //setTimeout is the caller of foo

使用.call时,它正在执行函数,而不是绑定this值并返回可调用函数。 setTimeout需要一个回调函数,但是你正在提供obj.foo的结果。 如果对setTimeout回调使用匿名函数,则应该看到预期结果:

setTimeout(function(){
 foo.call(obj);
}, 1000);