JavaScript 中的词汇 this
Lexical this in JavaScript
我刚读完你所不知道的 Javascript 系列丛书 "Scope and Closures"。这本书有一个附录讲到Lexical this。它给出了 this 如何失去其绑定以及如何使用箭头函数解决的示例。
我对第一种情况的例子有疑问。这是书中的例子:
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
函数不是作为方法,而是作为简单函数。这就是为什么你 "inherit" 一个 "global" 范围和 id
等于 3.
如果您使用 .
符号调用函数,就像在第二个示例中一样 - 您的调用范围是您在 .
之前和自 obj.id === 2
之后放置的任何内容 - 您会看到 2 打印出来。
理解这一点的关键是:setTimeout
获取一个函数的引用。它不知道你的函数是一个对象的方法。它对这个对象也一无所知。它得到的只是对 "code to execute" 的引用。在第二种情况下,您明确告诉解释器您要将函数 cool
作为对象 obj
的方法执行。
我刚读完你所不知道的 Javascript 系列丛书 "Scope and Closures"。这本书有一个附录讲到Lexical this。它给出了 this 如何失去其绑定以及如何使用箭头函数解决的示例。
我对第一种情况的例子有疑问。这是书中的例子:
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
函数不是作为方法,而是作为简单函数。这就是为什么你 "inherit" 一个 "global" 范围和 id
等于 3.
如果您使用 .
符号调用函数,就像在第二个示例中一样 - 您的调用范围是您在 .
之前和自 obj.id === 2
之后放置的任何内容 - 您会看到 2 打印出来。
理解这一点的关键是:setTimeout
获取一个函数的引用。它不知道你的函数是一个对象的方法。它对这个对象也一无所知。它得到的只是对 "code to execute" 的引用。在第二种情况下,您明确告诉解释器您要将函数 cool
作为对象 obj
的方法执行。