在 JavaScript 中对此进行词法分析



我刚刚读了"你不知道Javascript"系列的"范围和闭包"一书。这本书有一个附录,谈到了词汇。它给出了一个示例,说明如何丢失其绑定以及如何使用箭头函数解决。

我对第一种情况的例子有问题。这是本书的例子:

var obj = { id: 2, cool: function(){console.log(this.id)}}
id=3;
obj.cool();
setTimeout(obj.cool, 100);

这在打印预期结果时工作正常:第一次为 2,在 setTimeout 调用中为 3。

但是,如果我通过以下方式更改此呼叫:

var obj = { id: 2, cool: function(){console.log(this.id)}}
id=3;
obj.cool();
setTimeout(function(){obj.cool()}, 100); 

它两次打印 2

我的猜测是,通过将对 obj.cool 的调用包含在函数中,我正在创建一个 id 具有预期值的作用域。

我说的对吗?这是正确的解释吗?我错过了什么吗?

不完全是。在第一个示例中,setTimeout不是将cool函数作为方法调用,而是作为简单函数调用。这就是为什么你"继承"了一个"全局"作用域,id等于 3。

如果您使用.表示法调用函数,例如在第二个示例中 - 您的调用范围是您在.之前和自 obj.id === 2 年以来放置的任何内容 - 您会看到打印的 2

理解这一点的关键是:setTimeout只得到一个函数的引用。它不知道你的函数是一个对象的方法。它对这个对象也一无所知。它得到的只是对"要执行的代码"的引用。在第二种情况下,您明确告诉解释器您希望将函数cool作为对象obj的方法执行。

最新更新