let vs var in javascript



我知道让具有块范围,var具有功能范围。但是我不明白在这种情况下,使用让我们如何解决问题

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();

首先,输出将是四次,而不是五次(如您的评论中所述)。我将您的代码粘贴在babel repl中,这就是我得到的,

"use strict";
var arr = [1, 2, 3, 4];
var _loop = function _loop(i) {
setTimeout(function () {
   console.log(arr[i]);
}, 1000);
};
for (var i = 0; i < arr.length; i++) {
_loop(i);
}

您看到现在如何在内部工作吗?: - )

您仍然可以将var用于setTimeout。您可以使用立即启动的函数表达式(IIFE)在setTimeout上创建闭合,以便i的值通过setTimeout函数识别。

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

最新更新