gpt4 book ai didi

javascript - 为什么使用 setTimeout 函数时 let 和 var 绑定(bind)的行为不同?

转载 作者:行者123 更新时间:2023-11-28 03:37:17 24 4
gpt4 key购买 nike

此代码记录 6 ,6次:

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

但是这段代码...

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

...记录以下结果:

0
1
2
3
4
5

为什么?

是因为let每个项目以不同的方式绑定(bind)到内部范围,var保持最新值i

最佳答案

var 你有一个函数作用域,并且只有一个用于所有循环迭代的共享绑定(bind) - 即 i在每个 setTimeout 回调中都意味着循环迭代结束后 finally 等于 6 的相同变量。

let 你有一个 block 作用域,当在 for 中使用时循环,每次迭代都会得到一个新的绑定(bind) - 即 i在每个 setTimeout 回调中都意味着不同变量,每个变量都有不同的值:第一个是 0,下一个是 1 等等。

所以这个:

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

相当于仅使用 var:

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

使用立即调用的函数表达式来使用函数作用域,其方式与 let 示例中的 block 作用域类似。 .

不使用 j 可以写得更短名称,但可能不太清楚:

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

使用箭头函数甚至更短:

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

(但是如果你可以使用箭头函数,就没有理由使用 var 。)

这就是 Babel.js 将示例翻译为 let 的方式在 let 的环境中运行不可用:

"use strict";

(function timer() {
var _loop = function (i) {
setTimeout(function clog() {
console.log(i);
}, i * 1000);
};

for (var i = 0; i <= 5; i++) {
_loop(i);
}
})();

感谢Michael Geary在评论中发布 Babel.js 的链接。请参阅评论中的链接以获取实时演示,您可以在其中更改代码中的任何内容并立即观看翻译。看看其他 ES6 功能是如何被翻译的也是很有趣的。

关于javascript - 为什么使用 setTimeout 函数时 let 和 var 绑定(bind)的行为不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57593139/

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