JavaScript循环变量范围

关于JavaScript变量作用域的一个简单问题。

为什么What is 'i'? 10'函数打印i的值而不是返回undefined

$(document).ready(function () {
    for(var i = 0; i < 10; i += 1){
    }

     alert("What is 'i'? " + i);
});

我对JS还是很陌生,在我涉猎的几乎所有其他语言中,for循环范围内的声明将包含该循环的值,但在这种情况下为什么不这样?

即打印What is 'i'? 10'

BlackBox asked 2019-11-08T11:24:57Z
5个解决方案
65 votes

有关2605075610921862862144循环的“初始化参数”,请参见MDN:

表达式(包括赋值表达式)或变量声明。 通常用于初始化计数器变量。 该表达式可以选择使用var关键字声明新变量。 这些变量不是循环的局部变量,也就是说,它们与for循环所处的范围相同。该表达式的结果将被丢弃。

insertusernamehere answered 2019-11-08T11:25:25Z
54 votes

在引入constlet之前,JavaScript没有块作用域,只有var是函数作用域。 由于i的初始化是在一个函数中进行的,因此该变量可以在同一函数中的其他任何位置访问。

来自MDN:

重要提示:JavaScript没有阻止范围。 随块引入的变量的作用域为包含的函数或脚本,并且设置它们的效果在块本身之外仍然存在。 换句话说,block语句不会引入作用域。 尽管“独立”块是有效的语法,但是您不希望在JavaScript中使用独立块,因为如果您认为独立块在C或Java中的作用类似于此类块,则它们不会像您想的那样工作。

Devon Freitas answered 2019-11-08T11:26:07Z
16 votes

JavaScript人士正在努力解决此问题!

EcmaScript6(又名EcmaScript 2015)是去年夏天通过的JavaScript的最新版本,浏览器刚刚开始支持其功能。

这些功能之一是带有“ let”表达式的块范围局部变量。 截至目前(2016年4月),除Safari之外,大多数主流浏览器的当前版本均支持此功能。 很少有移动浏览器支持此功能。

您可以在此处了解更多信息(特别是,请参见“ for循环中的作用域变量”部分):[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/let]

您可以在此处检查当前浏览器的支持(查找“绑定-> let”行):[https://kangax.github.io/compat-table/es6/]

Matt Coarr answered 2019-11-08T11:27:02Z
10 votes

与其他语言(例如Java,C ++,C)不同,JavaScript不支持块作用域。 在循环或函数中声明变量后,如果执行此操作,其作用域将在函数体内

for(i=0; i<arr.length; i++) {
    var j=0;
    // ...
}

在这里,您的i变成了全局变量,而j变成了循环所在的函数或脚本的局部变量。

Hitesh Kumar answered 2019-11-08T11:27:37Z
9 votes
for(i=0; i<arr.length; i++) {
    var j=0;
    // ...
}

声明上面创建了一个全局变量i是不正确的。我相信您应该始终使用i来声明变量(除非您有意要一个“属性”而不是“变量”,这在99.99%的情况下是不太可能的 JS编码方案...)

在将初始值分配给i时省略i并不会创建局部变量甚至是全局变量,而是会为全局对象创建属性i(看起来/行为似乎很像全局变量,但它们之间存在一些细微的差别) 。

更好的是:

var i;
for(i=0; i<arr.length; i++) {
    var j=0;
    // ...
}

现在循环使用全局变量i(或函数局部变量i,如果此代码出现在函数中)

在var关键字的功能以及Java语言中的变量与属性的关系中了解更多信息

-注意,有点令人困惑的是您可以重新声明一个变量,例如在第二个循环中

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(分析)如何利用变量的“安全”重新声明]( 重新声明一个JavaScript变量)

在这个相关的SO问题中有一些关于在JS中重新声明变量的讨论(以及诸如i之类的循环变量):在循环内部或外部声明变量

有一个JavaScript模式可用于变量的单个声明

Matt Smith answered 2019-11-08T11:29:03Z
translate from https://stackoverflow.com:/questions/18465211/javascript-loop-variable-scope