gpt4 book ai didi

javascript - 在 for 循环中使用函数时范围问题的低级解释

转载 作者:行者123 更新时间:2023-11-28 15:04:40 25 4
gpt4 key购买 nike

昨晚我如饥似渴地读完了这本书。 You Don't Know JS: Scope & Closures .

fifth chapter ,关于作用域闭包,它给出了一个示例,说明 JavaScript 中的作用域机制如何导致 for 循环以不可预测的方式运行。

根据文本,以下 for 循环显示数字 6 五次。

for(var i=1; i<=5; i++) { setTimeout( function timer(){ console.log( i ); }, i*1000 ); }

这个问题可以通过在函数 timer() 内部创建一个变量 j 来解决,该变量引用当时 i 的当前值运行循环的特定实例。

for (var i=1; i<=5; i++) { (function(){ var j = i; setTimeout( function timer(){ console.log( j ); }, j*1000 ); })(); }

我可以接受这一点,并记住始终观察这种特殊性,但我更愿意理解为什么。

是否有人能在编译器、引擎和范围的上下文中提供详细解释,解释为什么第一个循环不起作用?

最佳答案

问题是,您在 for 循环中创建的闭包函数会记住对变量 i 的引用。 setTimeout 使对函数的调用异步(因此它在循环之后运行,无论您在那里设置什么延迟值),并且 i++ 更改 i 的值code> 每次迭代。当闭包运行时,所有闭包的值都相同,因为它们都引用同一个变量。在第二个示例中,您创建并运行一个匿名函数,该函数创建了自己的作用域,并通过执行 var j = i; 您在匿名函数的作用域中创建了一个变量 j包含此时 i 值的副本。在 setTimeout 中运行的函数会记住创建它的作用域中对变量 j 的引用,因此它具有您期望的值。

就我个人而言,我会将 i 作为参数传递给这个匿名函数,因为我发现它比上面显示的示例更清晰:

for (var i = 0; i < 5; ++i) {
(function (j) {
setTimeout(function timer() {
console.log(j);
}, j * 1000);
}(i))
}

现在,您可以使用let ,但目前仅在新浏览器和 Node 中;为了向后兼容,请查看 Babel .

关于javascript - 在 for 循环中使用函数时范围问题的低级解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39604093/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com