在 for-in 循环的内部或外部声明变量

Declaring variables inside or outside in a for-in loop

有这两个选项:

选项A:

var index;
for (index in myObject) {
  // Do something
}

选项 B:

for (var index in myObject) {
  // Do something
}

我不知道选项 B 中的变量 index 是在每次循环时都重新声明还是只重新声明一次。

这两段代码做的事情完全相同(大多数语言都是这种情况,例如 C、C++ 和 C# 等)。如果变量在每次迭代时都被重新声明,那么按照你的逻辑,它也会被重新初始化,并且会不断地遍历同一个对象。你的循环将是无限的。

附带说明,在 JavaScript 中,所有变量声明都被推送到函数范围;这意味着您可以在函数内的任何位置声明变量,甚至在嵌套循环内,而且它们只会被声明一次。

Link to the var documentation

Relevant SO question

Other relevant SO answer

由@torazaburo 提供编辑:

如果您想声明一个具有局部范围的变量(例如,一个只会在当前块中定义的变量,例如 forwhileif,可以使用let语句:

let var1 = 123;

它还允许您覆盖具有相同名称但在更高范围内声明的变量,例如文档中的示例:

function letTest() {
    let x = 1;
    if (true) {
        let x = 2;  // different variable
        console.log(x);  // 2
    }
    console.log(x);  // 1
}

查看完整文档(和示例)here

2016 年的首选方法是在循环头声明变量,使用 let:

for (let i = 0; i < max; i++) { }
     ^^^

这种方法与其他方法之间的性能差异可能很小,但在代码的稳健性和清晰度方面有很大的优势。

首先,对于 letifor 构造的局部变量,因此它不能 "leak out" 或修改其他一些 i在外部范围内。

其次,也许更重要的是,为循环的每次迭代创建新版本的 i。在技​​术术语中,"you get a fresh binding for each iteration if you let-declare a variable"(参见 this excellent article)。这解决了使用 i 的最终值在 for 循环内创建闭包的古老问题。我们现在可以写

for (let i = 0; i < 10; i++) {
  setTimeout(() => alert(i), i * 1000);
}

而不是必须做一些笨拙的解决方法,例如

for (var i = 0; i < 10; i++) {
  (function(i) {
    setTimeout(() => alert(i), i * 1000);
  }(i));
}

这是关于 SO 的无数问题的主题,你们中的许多人已经浪费了太多的大脑周期来学习。