【问题标题】:"var" or no "var" in JavaScript's "for-in" loop?JavaScript“for-in”循环中的“var”还是没有“var”?
【发布时间】:2011-08-08 16:42:30
【问题描述】:

在 JavaScript 中编写for-in 循环的正确方法是什么?浏览器不会对我在这里展示的两种方法中的任何一种提出投诉。首先,有一种方法是显式声明迭代变量x

for (var x in set) {
    ...
}

另外,这种读起来更自然但对我来说似乎不正确的方法:

for (x in set) {
    ...
}

【问题讨论】:

  • 在解决为什么 webpack 生成的捆绑文件在 for 循环中导致错误时遇到了这篇文章,其中 var 未用于声明迭代器 i:Uncaught ReferenceError: i is not defined。所以我将从现在开始使用它:/ webpack 奇怪地对待“全局”变量,更多信息请参见:stackoverflow.com/a/40416826

标签: javascript syntax for-in-loop


【解决方案1】:

我总是使用 ES2015 中引入的 let 块作用域。

for (let x in set) {
    ...
}

Additional reading and examples

【讨论】:

    【解决方案2】:

    你真的应该用var声明局部变量,always

    您也不应该使用“for ... in”循环,除非您完全确定这是您想要做的。对于遍历真实数组(这很常见),您应该始终使用带有数字索引的循环:

    for (var i = 0; i < array.length; ++i) {
      var element = array[i];
      // ...
    }
    

    使用“for ... in”遍历普通数组可能会产生意想不到的后果,因为您的循环可能会获取数组的属性而不是数字索引的属性。

    edit — 在 2015 年,也可以使用 .forEach() 遍历数组:

    array.forEach(function(arrayElement, index, array) {
      // first parameter is an element of the array
      // second parameter is the index of the element in the array
      // third parameter is the array itself
      ...
    });
    

    .forEach() 方法出现在 IE9 之前的 Array 原型中。

    【讨论】:

    • 在区分 Object for/in 循环与 Array for/length 循环方面,最好让您更清楚地使用 Array .forEach() 方法。
    【解决方案3】:
    for(var i = 0; ...)
    

    是一种常见的模式,但它不同于

    for(int i; ...)
    

    在 C++ 中,变量的范围不限于 for 块。事实上,var 被提升到封闭范围(函数)的顶部,因此本地 ifor 循环之前(当前范围/函数开始之后)和之后都有效.

    换句话说,做:

    (function(){ //beginning of your current scope;
     //...
     for(var i in obj) { ... };
    })();
    

    等同于:

    (function(){ //beginning of your current scope;
     var i;
     //...
     for(i in obj) { ... };
    })();
    

    ES6 有 let 关键字(而不是 var)来限制 for 块的范围。

    当然,您应该使用局部变量(使用 varletconst(在 ES6 中)声明的变量)而不是隐式全局变量。

    如果您使用"use strict";(应该如此)并且未声明ifor(i=0; ...)for(i in ...) 将失败。

    【讨论】:

      【解决方案4】:

      使用var 是最干净的方式,但两者都按照此处所述的方式工作:https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in

      基本上,通过使用var,您可以确保创建一个新变量。否则你可能会不小心使用了之前定义的变量。

      【讨论】:

        【解决方案5】:

        其实,如果你不喜欢 for 标题中的声明,你可以这样做:

        var x;
        for (x in set) {
            ...
        }
        

        正如该问题的其他答案所述,完全不使用 var 会产生不必要的副作用,例如分配全局属性。

        【讨论】:

          【解决方案6】:

          从一般的角度来看,第一个版本将用于必须存在于循环范围内的索引,而另一个版本将是调用循环构造函数的范围内的任何变量。

          如果你打算在 for 循环中使用循环的索引,而下一行中的其他人不需要这样做,最好用“var”声明变量,这样你就可以确定“x”是 for 循环的索引已初始化使用 0,而另一个,如果在此上下文中可以使用其他“x”变量,这将被循环的索引覆盖 - 那就是你会有一些逻辑错误 -。

          【讨论】:

            【解决方案7】:

            使用var,它会缩小变量的范围,否则变量会查找最近的闭包以搜索var 语句。如果它找不到var,那么它是全局的(如果您处于严格模式,using strict,全局变量会抛出错误)。这可能会导致以下问题。

            function f (){
                for (i=0; i<5; i++);
            }
            var i = 2;
            f ();
            alert (i); //i == 5. i should be 2
            

            如果您在 for 循环中写入 var i,则警报将显示 2

            JavaScript Scoping and Hoisting

            【讨论】:

            • 不回答问题,这是正常的for循环,不是for in。
            • i==5 的原因不是因为提升而不是 for 循环中缺少 var 吗?
            • 另一个重要方面是严格模式禁止隐式创建全局属性,因此使用标准的“for in”循环而没有 var 语句实际上会失败并返回 ReferenceError。
            • 但是,来自 Java,将 var 放入 for 头部看起来就像它在 for 循环中是本地的,但它不是。因此,我更喜欢下面user422039的风格。
            • 如果你碰巧在一个范围内有多个 for 循环怎么办?您要么必须重用索引(无 var),要么必须声明大量新变量(j、k、l、m、...),这些变量将永远不会再使用。
            【解决方案8】:

            第一个版本:

            for (var x in set) {
                ...
            }
            

            声明一个名为x的局部变量。第二个版本:

            for (x in set) {
                ...
            }
            

            没有。

            如果x 已经是一个局部变量(即,您在当前作用域(即当前函数)的较早位置有一个var x;var x = ...;),那么它们将是等价的。如果x 还不是一个局部变量,那么使用第二个将隐式声明一个全局变量x。考虑这段代码:

            var obj1 = {hey: 10, there: 15};
            var obj2 = {heli: 99, copter: 10};
            function loop1() {
                for (x in obj1) alert(x);
            }
            function loop2() {
                for (x in obj2) {
                    loop1(); 
                    alert(x);
                }
            }
            loop2();
            

            您可能希望这会提醒heythereheliheytherecopter,但由于x 是一个并且相同,它会提醒heytherethereheytherethere。你不想要那个!在 for 循环中使用 var x

            最重要的是:如果for 循环在全局范围内(即不在函数中),那么本地范围(如果您使用var x,则在其中声明范围x)是与全局作用域相同(如果使用不带 var 的 x,则隐式声明作用域 x),因此两个版本将相同。

            【讨论】:

            • 最后是一个完整的答案,带有解释和很好的例子。它确实回答了这个问题。
            【解决方案9】:

            我认为 var 出于性能原因是好的。

            Javascript 不会查看整个全局范围来查看 x 是否已经存在于其他地方。

            【讨论】:

              【解决方案10】:

              使用用var 声明循环变量的那个。隐式声明的变量具有不同的范围,这可能不是您想要的。

              【讨论】:

                猜你喜欢
                • 2021-10-26
                • 1970-01-01
                • 2015-08-28
                • 2018-11-28
                • 2015-11-25
                • 2017-04-14
                • 1970-01-01
                相关资源
                最近更新 更多