【问题标题】:JavaScript "for (var i = 0; ...) { ... }" browser incompatibilities?JavaScript“for (var i = 0; ...) { ... }”浏览器不兼容?
【发布时间】:2012-02-13 19:32:24
【问题描述】:

我有一段时间没有认真地进行 JavaScript 编程了,我正在为我的一些同事编写该语言的介绍指南。我想讨论循环的最佳实践,但有一个小细节我一直记在脑后:

在遍历数组时,我记得以下模式使用起来并不安全,因为有一些主流浏览器不支持它:

for (var i = 0; i < ls.length; i++) { ... }

相反,必须将 var 关键字移出数组,如下所示:

var i;
for (i = 0; i < ls.length; i++) { ... }

这是正确的吗?我已经搜遍了网络,无法确认这一点。是不是有些老浏览器不支持第一种方法?如果没有,哪些没有?

【问题讨论】:

  • 我个人认为第一个示例会失败的任何浏览器。
  • 2012 年常用的浏览器均不支持其中任何一个。它们完全一样。 (当我说“常用”时,我的意思是被不止一两个外围案例所使用;也许有人在某个地方运行 Netscape 3,但你明白了。而且 Netscape 3 可能工作了。)
  • 您希望获得多大的年龄?我们是在谈论 Netscape 和 IE3,还是您指的是 IE7 时间范围?
  • 在我使用 Javascript 编写代码的时间里(当然不是很长),我不记得在使用第一种方法时遇到过任何问题。您希望支持哪些浏览器的哪些版本?如果您可以访问所有这些,应该不会太难测试。
  • 此外,在您对这个项目感到震惊之前,网络上大量优质的 JavaScript 教程信息令人难以置信。那里有数以千计的此类教程,以及大量最新的书籍。

标签: javascript for-loop cross-browser


【解决方案1】:

“这是正确的吗?”

除非我们谈论的是一些非常非常旧的浏览器,否则我不知道今天使用的浏览器存在任何此类问题。


人们可能对第一个示例的唯一问题是它可能会让人误以为 JavaScript 具有 块作用域,但它没有 自 ES6 以来发生了变化,它确实块范围

在任一示例中,i 变量的作用域都将限定为封闭变量环境,无论封闭环境是函数还是全局环境。

【讨论】:

    【解决方案2】:

    相反,必须将 var 关键字移出数组

    不一定。关键是你不应该在i 之前忘记var 关键字,否则它将变成全局 变量。所以如果你这样做很好:

    for (var i = 0; i < ls.length; i++) { ... }
    

    您可以通过创建一个保存数组/集合长度的变量来提高上述代码的性能,而不是在每次迭代中一次又一次地读取它:

    for (var i = 0, len = ls.length; i < len; i++) { ... }
    

    顺便说一句,不用担心浏览器,该循环应该可以跨浏览器工作:)

    【讨论】:

    • 离题了,但这不是我第一次听说将长度存储在变量中是一项重要的优化。浏览器在后台做什么?我认为 .length 应该是一个恒定的时间查找,而不是计算出来的东西。
    • @thebossman:在 JavaScript 中,一切都是对象。在循环中,您使用的数组也是一个对象。在循环中,每次迭代都会一次又一次地读取它的值,例如,JS 在每次迭代时访问数组的属性,这比创建变量并为其分配长度要花费更多时间。当然,对于大多数用户或应用来说,这并不是什么大问题,但对于性能导向型或海量应用来说,这是至关重要的一步。
    • @thebossman:是的,但您必须经常查看它。将其存储在局部变量中意味着访问速度更快。
    • @Safraz 那么物业访问是什么昂贵的?听起来解释器/编译器应该对此进行优化。很有趣,谢谢。
    【解决方案3】:

    假设您不支持任何早于 IE6 的浏览器,这应该不是问题。

    【讨论】:

    • 在 IE 3.02 和 Netscape 2.0 中都没有
    【解决方案4】:

    JavaScript 实际上声明的是函数级范围而不是块范围。声明的变量被提升到其函数的顶部。我要说的是你的例子实际上是相同的。即使在for 语句中使用var 关键字,i 变量也可以在循环外访问。

    您唯一需要注意的是,如果您省略 var,该变量将是全局变量,而不是仅限于函数。

    【讨论】:

      【解决方案5】:

      今天遇到了这个

         for(var i=0; i < t; i++) {
      //do whatever
      }
      

      我的 jscript 在一个从 html 文件调用的 xsl 文件中 - 在 IE 中运行良好,但在其他浏览器上却不行 - 代码会崩溃并且什么也不显示

      幸运的是,我可以将其更改为适用于所有经过测试的浏览器

      for(var i=0; i != t; i++) {
      do whatever}
      

      也要注意 https://support.microsoft.com/en-us/help/273793/how-to-include-client-side-script-functions-in-an-xsl-document

      【讨论】:

        【解决方案6】:

        不是你要求的,但你可以使用 jQuery 来做到这一点,如下所示:

        $.each(ls, function(i,value){
        ...
        });
        

        【讨论】:

          猜你喜欢
          • 2012-10-19
          • 1970-01-01
          • 2011-07-27
          • 2011-09-01
          • 1970-01-01
          • 2012-09-20
          • 2014-09-12
          • 1970-01-01
          • 2019-05-31
          相关资源
          最近更新 更多