简短回答:不,JS将所有变量声明提升到作用域顶部,无论您声明了多少次:
var i = 0
for (var i=0
{
var j = i%2
}
将被翻译为
var i, j; //i is undefined at this point in the code.
for (i = 0;i<10;i++)
{
j = i%2;//declared 10 times, on each iteration
}
在你的第一个示例中,你将i
声明为函数作用域中的变量,这是你必须做的,以避免使全局范围混乱。这些变量使用的内存在函数调用时分配,在函数返回时释放(粗略地说,闭包是一个例外,但那会让我们偏离主题)。考虑以下代码:
var i = 10;
function someF()
{
var i = 1;
alert(i);
}
someF();//alerts 1 <-- value of i, local to someF
alert(i);//10, global i is unchanged
但如果你省略了 var
:
function someF()
{
i = 1;
alert(i);
}
你会看到数字1被警告了两次。如果JS在当前作用域中找不到变量声明,它将查找更高的作用域,直到找到一个var。 如果没有找到变量,JS将在最高作用域(全局)为您创建一个。 有关隐含全局变量的更详细示例,请在此处检查我的答案,或者阅读MDN页面,特别是关于名称冲突的部分。
最后,我想补充一点,全局变量,特别是隐含全局变量,是有害的。并且要知道,ECMA6标准明显远离全局变量,并引入对真正块级作用域的支持。您可以在这里看到。
哦,如果你想检查一个函数是否使用隐含全局变量:'use strict';
是一个很好的东西:
(function()
{
'use strict';
var localVar = 123;
impliedGlobal = 123;
}());
如您所见,隐式全局变量是不允许的。请参考MDN关于严格模式的完整解释
i
。每次调用addNumbah1()
,i
的值都将是1
。第二个函数则声明了一个全局变量i
,并在每次调用时重置为新的值,但在每个函数中都使用了全局变量。 - Michael Berkowski