嵌套循环中 Javascript 变量的作用域

scope of Javascript vars in nested loops

本文关键字:作用域 变量 Javascript 嵌套循环      更新时间:2023-09-26

我认为用"var"声明某些东西会使它成为其范围的本地内容。 那么,为什么这段代码似乎没有两个名为"len"的不同变量,而只有一个呢?

for (var i=0, len=3; i<len; i++) {
    for (var j=0, len=1; j<len; j++) {
        console.log('i=' + i + ', j=' + j + ', len=' + len);
    }
}

在输出中,我只得到一行,而不是三行。 为什么?

(在Chrome和Safari上是真的,没有检查过其他人。

因为用 var 声明的变量绑定到函数作用域,而不是像许多其他语言那样绑定到块作用域。例如,这工作得很好:

if (true) {
  var thing = 'something';
}
console.log(thing); // 'something'

但是,这将不起作用,因为范围是由函数定义的。

function a() {
  var thing = 'something';
}
function b() {
  console.log(thing); // ReferenceError
}
a();
b();

我认为用"var"声明某些东西会使它成为其范围的本地内容。

它确实:函数作用域(或全局作用域,如果您全局使用它)。与许多类似语言中的变量声明不同,var没有作用域。因此,您的循环在仅输出一行后终止,因为您在内部循环的初始值设定项中将len设置为 1,这与外部循环使用的len相同。

var的这个和其他一些方面已经足够麻烦了,以至于它已经被修复了:在ES2015(最新的JavaScript规范)中,新的let具有块作用域(并且在循环for周围有一些特殊的挥手),因此您的示例可以使用let

// NOTE: Only works on browsers supporting `let`!
"use strict"; // (Some browsers don't support let outside of strict mode yet)
for (let i = 0, len = 3; i < len; i++) {
  for (let j = 0, len = 1; j < len; j++) {
    console.log('i=' + i + ', j=' + j + ', len=' + len);
  }
}

但我不建议使用两个这样的嵌套len。即使 JavaScript 不会混淆,也不能保证

程序员不会追随你。

let是ES2015的几个真正好的地方之一。在除极少数边缘情况外的所有情况下,let都是新的var。当然,在所有目标浏览器都更新了他们的 JavaScript 引擎之前,你必须坚持使用 var 或转译。

您认为将某些内容声明为 var 会使其成为范围的本地内容是正确的。这就是为什么当您在内部 for 循环中进行比较时,使用的 len 值是在内部循环中声明的值。因此只有一行输出。