繁体   English   中英

为什么变量值在 var 和 setTimeout 中不同

[英]Why variable value is different incase of var and let in setTimeout

在练习 JavaScript 时,我遇到了一个疑问,我正在使用 var 和使用 let 关键字打印变量 i 值,并且两次都得到不同的结果但无法理解为什么我需要对此进行一些解释?

声明ilet

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

output 是从 0 到 5 的计数:

另一方面,将i声明为var

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

output 是 6 的 6 倍:

原因很简单。 let是块范围的。 这意味着当你跳出你的for循环的scope时,它就不存在了。 var scope 更宽。 这里发生的是 for 循环将i递增 5 次,然后在第一个 setTimeout 触发(不到 1 秒)和全局 scope 之前以i = 6退出循环。用let声明的i来自 function scope ,而用 var 声明的i来自外部 scope

let 和 var 的区别:“let”和“var”有什么区别?

使用for循环,每次迭代都有自己的scope

  1. let作为其block scope的情况下,每次迭代都有自己的i变量,其值将在setTimeout中关闭,因此每个setTimeout将 output 正确的索引

  2. var的情况下,因为它是一个functional scope ,每次迭代都会覆盖前一次,并且在执行setTimeouti的值将在迭代结束时为6 ,将记录在所有 setTimeout 回调中。

i的 scope 使用let和使用var时不同

这里:

for(let i=0;i<=5;i++){ // i will not be available outside of the block below

setTimeout(
function clog(){
console.log(i)

},i*1000 ); 
// mentionning the variable i will cause a Reference error starting from here

而对于vari被提升,并且在当前函数块的开头没有值定义,在循环结束时i仍然存在,并且已经发生了变化,所以当setTimeout回调被触发时,循环将已经完成, i将得到它的最终值,这是第一个不匹配循环条件的值(即6 )。

这是因为 javascript 的全局 (var) 或块范围 (let) 值处理。

在 var 中,变量 i 是全局变化的,循环在 settimeout function 运行之前完成,因此 i 全局变为 6,控制台日志将它写为 6。

在 let 中,对于每个循环迭代都有一个 i 变量只属于 scope 和 settimeout function 接受它,所以即使循环完成它的作业控制台日志也会将本地变量 i 写入 0,1,2,3,4,5。

我希望我正确地告诉自己。

参考: Javascript MDN

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM