在使用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结束才结束。是整个开关/案例的范围吗?
答案 0 :(得分:15)
Javascript不使用块范围。
因此,所有局部变量都在声明它们的整个函数的范围内。
但是,在您的特定情况下,没有类似C语言(我知道),其中每个case
语句形成一个独立的范围。
例如,以下C#代码将无法编译:
switch(someVar) {
case 1:
int a;
break;
case 2:
int a; //'a' is already defined
break;
}
答案 1 :(得分:4)
是整个开关/案例的范围吗?
不,如果您在函数之外,它适用于整个包含函数或全局范围。
(有一些模糊的例子,其中JavaScript引入了额外的范围,但就是它。)
警告:'i'已定义
我不同意这是一个警告。我希望保留代码不变,块的独立使用变量i
。
它希望您做的是从第一个声明中移除var
,或者在切换之前添加var i
并从所有var
中移除for
秒。但是现在这些块并不孤立,快速剪切粘贴(例如,将switch
重构为单独的function
)会留下引用{{1}的循环尚未声明的i
。这是一个偶然的全局,它是一个可怕的JS陷阱,这可能是一个真正的调试痛苦。
JSLint提出同样的投诉。我通常会忽略它。在一个块中两次声明变量var
没有坏处。
答案 2 :(得分:0)
即使javascript具有块范围,也存在一种贬低功能,这种功能有点取消了每个case
范围内的概念...