在JavaScript中用词汇表示

时间:2018-03-06 23:09:27

标签: javascript this lexical-scope

我刚读过这本书"范围与关闭"您不知道Javascript的系列节目。这本书有一个附录,谈论Lexical这个。它给出了这个如何失去绑定以及如何使用箭头函数解决的示例。

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

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具有期望值的范围。

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

1 个答案:

答案 0 :(得分:2)

不完全是。在第一个示例中,setTimeout调用您的cool函数不是一种方法,而是一个简单的函数。这就是为什么你“继承”一个“全局”范围而id等于3。

如果您使用.表示法调用某个函数,就像在第二个示例中一样 - 您的调用范围是您在.之前和obj.id === 2之前放置的任何内容 - 您看到2已打印。

理解这一点的关键是:setTimeout仅获取对函数的引用。它不知道你的函数是一个对象的方法。它对此对象也一无所知。它只是对“执行代码”的引用。在第二个场景中,您明确告诉解释器您要执行函数cool作为对象obj的方法。