我目前正在阅读你不知道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);
可以解决这个问题,我只想试着理解这本摘自本书的内容。
答案 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);