在 Javascript 中声明 var 用于循环声明

Declaring var inside Javascript for loop declaration

本文关键字:声明 用于 循环 var Javascript      更新时间:2023-09-26

我确定我已经阅读了关于SO的讨论,但找不到它。简单地说,在循环的声明中声明 for 循环的增量是否有缺点?这有什么区别:

function foo() {
    for (var i=0; i<7; i++) {
        // code
    }
}

。而这个:

function foo() {
    var i;
    for (i=0; i<7; i++) {
        // code
    }
}

既然JS有函数作用域,那么任何一个都应该没问题,对吧?是否存在前一种方法会导致问题的边缘情况?

如果它们是相同的,为什么Crockford/JSLint都是"没办法

"呢?

这些是完全相同的。 javascript 中的所有局部变量都有函数作用域,这意味着它们对于声明它们的整个函数都是活动的。 起初这通常是违反直觉的,因为大多数大括号语言将变量的生命周期范围限定为声明它们的块。

一部分Javascript开发人员非常喜欢第二种形式。 其基本原理是,由于所有变量都有函数作用域,因此您应该在函数级别声明它们,以使生命周期明确,即使对于那些不熟悉Javascript的人也是如此。 这只是一种风格,绝不是硬性规定

编辑

请注意,随着 ES6 let 的引入,您现在可以在循环中使用 let 来获取真正的块范围变量 更多详细信息

for(let i = 1; i <= 5; i++) {
   setTimeout(function(){
       console.log('Value of i : ' + i);
   },100);
}

在循环标头中使用 var 声明的问题在于它具有欺骗性。 看起来您正在声明一个变量,其范围仅限于for循环,而它实际上存在于函数中的任何地方 - 包括在声明之前

var i = 1;
function foo() {
   console.log(i);                     // 'undefined'
   for (var i=1; i<100; ++i) {
   }
}

即使console.log调用发生在声明本地i之前,它仍然在它的范围内,因为它在同一个函数内。因此,尚未为其分配任何值的本地i是传递给log的内容。这可能令人惊讶;对于不熟悉Javascript范围规则的人来说,这当然不是显而易见的。

从 ECMAScript 2015 开始,有一种更好的方法来声明变量:let 。用 let 声明的变量是包含它们的块的局部变量,而不是整个函数。因此,上述代码的此版本将按预期打印1

let i=1; // could use var here; no practical difference at outermost scope
function foo() {
  console.log(i);               // 1
  for (let i=1; i<100; ++i) {
  }
}

因此,现代Javascript中的最佳实践是用let而不是var声明变量。 但是,如果你坚持使用 ECMAScript 2015 之前的实现,那么在函数顶部声明所有变量而不是等到第一次使用就不那么令人困惑了。

没有区别,但我更喜欢第二种方式(每个 Crockford),因为它明确表明变量在 for 循环之外可用:

function() {
    for(var i=0; i<7; i++) {
        // code
    }
    // i is still in scope here and has value 7
}

这两者都是完全相同的事情。

这两个代码块是相同的。for循环的第一个语句在 for 循环启动之前执行,循环正在运行,而第二个语句为 true,并且每次循环迭代一次时运行第三个语句。

这意味着

for(var i = 0; i < 8; i++) {
    //some Code
}

与 相同

var i = 0;
for(;i < 8;) {
    //some Code
    i++;
}

(后面的分号是告诉计算机i < 8实际上是第二个语句,而不是第一个语句)。