简短的回答:不,JS 将所有变量声明提升到范围的顶部,无论您声明了多少次:
var i = 0
for (var i=0;i<10;i++)
{
var j = i%2;//declared 10 times, on each iteration
}
将被翻译成
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;//ok
impliedGlobal = 123;//TypeError!
}());
如您所见,不允许使用隐含的全局变量。完整解释见MDN on strict mode