【问题标题】:What is the JavaScript variable scope in a switch / case statement?switch / case 语句中的 JavaScript 变量范围是什么?
【发布时间】:2010-03-26 15:25:24
【问题描述】:

在使用 ASP.NET MVC 创建 JavaScript 时,我注意到几个范围警告,并意识到我在理解 switch / case 语句中的变量范围时遗漏了一些东西。

警告:'i' 已定义指的是案例 b 和案例 c

我的代码如下所示:

switch(element) {
  case 'a':
   for(var i=0; i < count; i++){
    do something
   }
   break;

  case 'b':
   for(var i=0; i < count; i++){
    do something
   }
   break;

  case 'c':
   for(var i=0; i < count; i++){
    do something
   }
   break;
}

我认为范围以每个 break 语句结束,但似乎范围直到 switch/case 结束才结束。是否适用于整个开关/案例?

【问题讨论】:

    标签: javascript asp.net-mvc scope


    【解决方案1】:

    Javascript 不使用块作用域。

    因此,所有局部变量都在声明它们的整个函数的范围内。

    但是,在您的特定情况下,没有类似 C 的语言(据我所知)其中每个 case 语句形成一个独立的范围。
    例如,以下 C# 代码将无法编译:

    switch(someVar) {
        case 1:
            int a;
            break;
        case 2:
            int a;        //'a' is already defined
            break;
    }
    

    【讨论】:

    • 是的。我一定是在这个上睡着了,因为乍一看它似乎是对的。但是很高兴编译器警告让我知道我什么时候睡着了。谢谢你这么好的回答。
    • 请注意,在类 C 语言(不是 Javascript)中,如果您愿意,您可以在案例之后自己创建一个范围:case 1: { ... }
    • 仅供参考,现在 ES6 语法允许块作用域,因此可以逐个创建作用域
    • 请注意,即使现​​在 JS 中存在块作用域,case 默认仍不会创建自己的作用域。例如,在不同的连续cases 中使用let 关键字会引发错误。
    【解决方案2】:

    是否适用于整个开关/案例?

    不,它适用于整个包含函数,或者如果您在函数之外,则为全局范围。

    (在少数情况下 JavaScript 引入了额外的作用域,但仅此而已。)

    警告:“i”已定义

    我真的不同意这是一个警告。我宁愿保留代码原样,让块独立使用变量i

    它想要你做的是从除第一个声明之外的所有声明中删除var,或者在开关之前添加var i,并从所有fors 中删除var。但是现在这些块不再是独立的了,快速剪切和粘贴(例如,将switch 重构为单独的function​s)会给您留下引用i 的循环,而这还没有声明var。这是一个偶然的全局,它是一个可怕的 JS 陷阱,调试起来真的很痛苦。

    JSLint 提出了同样的抱怨。我通常会忽略它。在一个块中声明一个变量var 没有坏处。

    【讨论】:

    • 是的,我知道它有效。我只是不喜欢在生产代码中出现警告。但是在办公室里的一次谈话表明,jQuery 做同样的事情。所以我可以离开它。谢谢你的好回答。
    【解决方案3】:

    即使 javascript 有块作用域,也有一个贯穿功能,这有点使每个case 具有作用域的概念不合格...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-23
      • 1970-01-01
      • 2020-12-27
      • 1970-01-01
      • 2013-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多