【问题标题】:Re-declaring variables in Javascript在 Javascript 中重新声明变量
【发布时间】:2016-10-16 09:21:18
【问题描述】:

我今天(通过艰难的方式)发现 JavaScript 允许这样做,而不会产生任何错误:

for(var i = 0; i < 100; ++i){
    /* do some stuff */
    for(var i = 0; i < 200; ++i){
        /* do some more stuff */
    }
}

我偶然为两个循环使用了相同的标识符i

JavaScript 编译器/解释器不会产生错误(如 Java),也不会创建一个不同的变量来隐藏外部循环上的变量(如 C++)。它们引用同一个变量,所以外层循环只会运行一次!

为什么会这样?这种行为在任何情况下都有用吗?

【问题讨论】:

  • Is this behaviour useful in any circumstance at all - 可能是 - 我想不出每一种情况都可以明确地说出来:p
  • 不,它根本没有用。这是语言的主要问题之一。但是对于 es6,您可以使用块范围的变量 letconst
  • @synthet1c 感谢您关注letconst。我不知道 JavaScript 会将变量提升到函数声明的顶部。呸。而且我认为只有 VBA 才能做到这一点。
  • @Bernard 另请注意,在内部 for 循环中放置 break 语句会导致其他问题。
  • @Bernard 迭代将返回外循环,然后返回内循环,其中任何一个都没有完成,最终永远不会停止重复该过程。也就是说,直到无限递归停止Task manager

标签: javascript scope variable-declaration redeclaration


【解决方案1】:

如您所见,第一个值出现两次,所有其他值最多出现一次。

所以使用这种模式完全没有意义。

重新声明被移到顶部,并且对同一个变量只使用一次。

for (var i = 0; i < 10; ++i){
    console.log('outer', i);
    for (var i = 0; i < 20; ++i){
        console.log('inner', i);
    }
}
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 我知道我的示例在实践中没有任何意义,但是很容易犯错误,将现有标识符用于新变量。我想知道,作为一门语言,为什么 JavaScript 允许这种毫无意义的代码(这显然是程序员的错误)在没有任何警告或错误的情况下工作。
  • 编译器不检查是否有意义。重新声明变量不会导致错误,即使'use strict'; 也不会导致错误。我建议在 propgram/function 顶部声明所有变量,并且不要在 for 循环初始化部分中使用 var 语句。
【解决方案2】:

我找不到任何用处。能够在没有任何警告或错误的情况下执行两次 var i; 似乎是该语言的缺陷。

正如this comment 中所指出的,使用let 而不是var 解决了这个问题。虽然var 被提升到函数体的开头,但let 只被提升到最近的{。不过,let 尚未得到广泛支持,因此如果您需要保持与旧版浏览器的兼容性,则不应立即使用它。

JSHint 等代码检查工具可以帮助检测此类重复声明问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    • 1970-01-01
    • 2013-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多