javascript - 让 vs var 在 javascript 中

标签 javascript closures var let

<分区>

我知道 let 具有 block 作用域,而 var 具有功能作用域。但是我不明白在这种情况下,使用 let 将如何解决问题

const arr = [1,2,3,4];
for (var i = 0; i < arr.length; i++) {
setTimeout(function() {
   console.log(arr[i]) 
}, 1000);
} // Prints undefined 5 times

const arr = [1,2,3,4];
for (let i = 0; i < arr.length; i++) {
setTimeout(function() {
   console.log(arr[i]) 
}, 1000);
} // Prints all the values correctly

最佳答案

这都跟变量的作用域有关。让我们尝试将这两个部分包装成函数,并观察输出:

function test() {
  // `i` will be declared here, making it a non-for-loop scoped variable
  const arr = [1, 2, 3, 4];
  for (var i = 0; i < arr.length; i++) {
    setTimeout(function() {
      console.log(arr[i])
    }, 1000);
  } // Prints undefined 5 times
}

test();

所以在第一种情况下,i会被提升,并且由于setTimeout的异步特性,i会立即变成4循环结束而无需等待。这将使 arr[i] 指向数组中的 undefined 元素。

在第二种情况下,i 没有被提升,并且对循环的每次迭代都有范围访问,使 i 准确地可用于 console.log声明。因此结果符合预期:

function test() {
  const arr = [1, 2, 3, 4];
  for (let i = 0; i < arr.length; i++) {
    setTimeout(function() {
      console.log(arr[i])
    }, 1000);
  } // Prints all the values correctly

}

test();

关于javascript - 让 vs var 在 javascript 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48002533/

相关文章:

javascript - 我正在尝试使用 jquery 和 ajax 将多个数据发送到另一个页面以检查数据库中是否存在值

swift - 如何在 Swift 中声明一个作为属性名称的函数参数

scala - Scala 中的惰性求值、thunk 和函数闭包

c# - 闭包捕获的变量也会修改原始变量

ios - Swift 中的@IBOutlet 变量

css - 可变 href 链接?计时器上的图像

javascript - 安全地解析和评估用户输入

javascript - 使用 PHP 在数据库中存储动态创建元素的 HTML

javascript - 在 JavaScript 中使用本地文件作为数据源

第一次更改颜色后,用于轮廓颜色闪烁的 JavaScript setInterval 不起作用