JavaScript如何在循环中创建变量

3
var i,j;
for (i=0; i<30; i++) {
    for (j=0; j<10; j++) {
        // do something
    }
}

对比

for (var i=0; i<30; i++) {
    for (var j=0; j<10; j++) {
        // do something
    }
}

第二种方式由于JavaScript的作用域逻辑而创建和销毁了j 30次?我更喜欢使用第一种方式,但我不确定是否有区别。有吗?

4
var 会被提升。个人认为第一种写法更简洁,但两种写法是等价的。 - Paul S.
2
关键在于你误解了“javascript作用域”的逻辑,for语句并没有特殊的作用域,函数才有。 - adeneo
第二种方法会创建和销毁j变量30次。如果使用for (let j=0; j<10; j++),就会出现这种情况。 - A. Wolff
3个回答

14

JavaScript不会提升变量的声明(hoists the variable declarations)。所以,所有变量的声明都会提前到它们所在函数的顶部。因此,这些变量只会被创建一次,它们的值会在循环中每次发生改变。


不好意思打扰一下,但是对于第二个例子,顶部提升的变量每次都会被覆盖吗?因为它每次都以 var 关键字开始。 - AL-zami
@al-Zami 不会被覆盖,除非有赋值操作。Javascript 实际上没有自动初始化。 - Luaan

6

@thefourtheye和@Remigius Kijok的回答都是正确的。每当变量在函数内(或全局范围内)被声明并初始化时,声明都会提升到该范围的顶部。

您可以通过将您拥有的任何一个for循环包装在一个函数中,然后在浏览器中执行该函数来自行查看。具体而言,通过在函数顶部设置断点,您将能够看到在函数执行之前所有变量都被声明并初始化为值undefined

var loopy = function () {
  for (var i = 0; i < 5; i += 1) {
    for (var j = 0; j < 3; j += 1) {
      console.log('i is ' + i + ' and j is ' + j);
    }
  }
};

loopy(); // place break point here

变量提升

从图片上可以看出,我正在使用Chrome的开发工具,在loopy()执行时设置断点。在进入函数之后,但在执行任何一个for循环之前,变量i和j都被声明了,但是值为undefined


嗯,开发工具并不是展示这个问题的最佳方式,因为结果很大程度上取决于编译器如何优化代码(请参阅[我在这里的回答](https://dev59.com/nGEh5IYBdhLWcg3w32xG#21918024))。但是,您可以通过显示`function(){j = 0; console.log(j); if (false) { var j = 1; } console.log(j)}打印出0 0来演示这一点 -- 即使从未评估带有var的语句,j`仍然存在并且可以保存一个值。 - p.s.w.g
如果您查看作用域变量部分,您可以清楚地看到在函数执行任何代码行之前,“i”和“j”变量都是“未定义”的。 - wmock

5
您的两个版本是相同的,没有区别。变量j不会被创建和销毁30次。

提供一个有效的理论/实践证明来支持你的假设将是理想的。 - VisioN

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接