关于JavaScript变量范围的快速问题。
为什么alert()
函数会打印i
的值而不是返回undefined
?
$(document).ready(function () {
for(var i = 0; i < 10; i += 1){
}
alert("What is 'i'? " + i);
});
我对JS很新,在几乎所有其他语言中我都涉及过,for循环范围内的声明将包含该循环的值,但在这种情况下不是,为什么?
即。打印What is 'i'? 10'
。
答案 0 :(得分:64)
请参阅MDN了解&#34; initialization parameters&#34;一个for
-loop:
表达式(包括赋值表达式)或变量声明。通常用于初始化计数器变量。该表达式可以选择使用var关键字声明新变量。 这些变量不是循环的局部变量,即它们与for循环所在的范围相同。此表达式的结果将被丢弃。
答案 1 :(得分:54)
在引入const
和let
之前,JavaScript没有阻止范围,只有var
是功能范围的。由于i
的初始化在一个函数内,因此该变量可以在同一函数中的任何其他位置访问。
来自MDN:
重要说明:JavaScript没有块范围。使用块引入的变量的范围限定为包含函数或脚本,并且设置它们的效果将持续超出块本身。换句话说,块语句不引入范围。虽然“独立”块是有效的语法,但您不希望在JavaScript中使用独立块,因为如果您认为它们在C或Java中执行类似此类块的操作,则它们不会按照您的想法执行操作。
答案 2 :(得分:16)
javascript人员正试图解决这个问题!
EcmaScript6(又名EcmaScript 2015)是去年夏天推出的最新版javascript,浏览器刚刚开始支持其功能。
其中一个功能是具有“let”表达式的块范围局部变量。截至目前(2016年4月),主流浏览器的大多数当前版本都支持Safari,除了Safari。很少有移动浏览器支持此功能。
您可以在此处阅读更多相关信息(特别是请参阅“for循环中的let-scoped变量”部分): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
您可以在此处查看当前的浏览器支持(查找行Bindings - &gt; let): https://kangax.github.io/compat-table/es6/
答案 3 :(得分:10)
与其他语言(例如:Java,C ++,C)不同,JavaScript不支持块范围。一旦在循环或函数中声明变量,如果你这样做,它的范围就在函数体内
for(i=0; i<arr.length; i++) {
var j=0;
// ...
}
此处您的i
成为全局变量,j
成为循环所在的函数或脚本的本地变量。
答案 4 :(得分:9)
for(i=0; i<arr.length; i++) {
var j=0;
// ...
}
说明上述内容创建全局变量i
是不正确的。我相信你应该总是使用var
来声明变量(除非你故意想要一个&#39;属性而不是一个&#39;变量&#39; - 这在99.99%的JS中是不太可能的编码方案......)
在为var
分配初始值时忽略i
不是创建本地变量甚至是全局变量,而是为全局对象创建属性i
(可能看起来/行为大多像一个全局变量 - 但它们有一些微妙的差异。)
更好的是:
var i;
for(i=0; i<arr.length; i++) {
var j=0;
// ...
}
现在循环使用全局变量i
(或函数局部变量i
,如果此代码出现在函数中)
在what is function of the var keyword和variables vs. properties in Javascript
了解详情- 请注意,有些令人困惑的是,您可以重新声明变量,例如在第二个循环中
for(var i=0; i<9; i++){
document.write('i = ' + i + '<br>');
}
for(var i=0; i<9; i++){
document.write('i = ' + i + '<br>');
}
这似乎是有效的(我测试时没有错误)。您似乎可以在JavaScript中重新声明变量 - 但除非有特殊情况,否则它可能并非每个好主意 - 请参阅此相关问题,提及[Google Analytics(分析)如何使用&#39; safe&#39 ;重新声明变量](Redeclaring a javascript variable)
在这个相关的SO问题中,有一些关于在JS中重新声明变量(以及像i
这样的循环变量)的讨论:declare variables inside or outside the loop