我知道函数声明被提升到其作用域的顶部。这允许我们在 JavaScript 中实际声明之前使用这些函数:
sayHello(); // It works!
function sayHello() {
console.log('Hello');
}
我也明白闭包使函数能够保留对在同一范围内声明的变量的引用:
function outerFxn() {
let num = 0;
function innerFxn() {
console.log(num);
num++;
}
return innerFxn;
}
const logNum = outerFxn();
logNum(); // 0
logNum(); // 1
logNum(); // 2
到现在为止还挺好。但是这里有一些奇怪的地方,我希望有人能确切地解释发生了什么......
function zero(cb) {
return setTimeout(cb, 0);
}
function test1() {
let txt = 'this is a test message';
function log() {
console.log(txt);
}
zero(log);
}
在上面的示例中,该log
函数保留对创建它的作用域的引用,并保留txt
变量。然后,当稍后在 中执行时setTimeout
,它成功地记录了txt
变量的值。伟大的。然后就是这个...
function zero(cb) {
return setTimeout(cb, 0);
}
function test1() {
function log() {
console.log(txt);
}
let txt = 'this is a test message';
zero(log);
}
我已经将log
函数声明移到了作用域的顶部(无论如何它都会被提升到那里,对吗?),然后我声明了txt
它下面的变量。这一切仍然有效,我不知道为什么。当's 和's 没有被提升时,如何log
保留对txt
变量的引用?是否对闭包范围进行了整体分析?我可以在这里一步一步地对 JavaScript 引擎正在做的事情进行一些清晰的说明。谢谢你的土地!let
const
“是否对闭包范围进行了整体分析?” - 是的。闭包保留范围在你(词汇上)离开它的那一刻。在您的示例中,txt
当您到达}
in时确实存在test1
,因此它在范围内,并且log
访问它没有问题。
注意上面的“词法”:绑定是在运行之前完成的,只有你的块结构才是重要的。所以即使这样也可以,尽管从“动态”的角度来看它不应该:
function test1() {
function log() {
console.log(txt);
}
zero(log);
let txt = 'this is a test message';
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句