JavaScript循环variables作用域

只是一个关于JavaScriptvariables范围的简单问题。

为什么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' What is 'i'? 10'被打印。

有关for -loop的“ 初始化参数 ”,请参阅MDN:

一个expression式(包括赋值expression式)或variables声明。 通常用于初始化计数器variables。 这个expression式可以有select地用var关键字声明新的variables。 这些variables对于循环来说不是本地的,即它们与for循环处于相同的范围内。这个expression式的结果被丢弃。

JavaScript没有块范围,只是函数范围。 由于i的初始化在一个函数内,因此该variables可以在同一个函数中的任何其他位置访问。

来自MDN :

重要提示:JavaScript没有块范围。 用块引入的variables作用于包含函数或脚本,并将其设置的效果保留在块本身之外。 换句话说,块语句不会引入范围。 尽pipe“独立”块是有效的语法,但是你不想在JavaScript中使用独立块,因为如果你认为它们在C或Java中做类似的块,它们就不会像你认为的那样做。

JavaScript的人正试图解决这个问题!

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

其中一个特性是带有“let”expression式的块范围局部variables。 截至目前(2016年4月),除Safari之外,大多数主stream浏览器都支持这个版本。 很less有移动浏览器支持这一点。

您可以在这里阅读更多关于它的信息(特别是,参见for循环中的let-scopedvariables一节): https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

你可以在这里查看当前浏览器的支持(查看行Bindings – > let): https : //kangax.github.io/compat-table/es6/

与其他语言(例如:Java,C ++,C)不同,JavaScript不支持块范围。 一旦你在一个循环或者一个函数中声明一个variables,那么它的作用域就在函数体内

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

在这里你的i变成了一个全局variables, j变成了循环所在的函数或者脚本的本地variables。

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

声明上面创build一个全局variablesi是不正确的。 我相信你应该总是使用var来声明variables(除非你故意要一个'属性'而不是'variables',这在99.99%的JS编码场景中是不太可能的)

当给i赋一个初始值时,省略var不是创build一个局部variables,甚至是一个全局variables,它为全局对象创build一个属性i (可能看起来/performance得像一个全局variables – 但是它们有一些细微的差别) 。

更好的是:

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

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

请参阅关于var关键字和variables的 函数以及Javascript中的属性的更多信息

– 注意,有点令人困惑的是,你可以重新声明一个variables,例如在第二个循环中

 for(var i=0; i<9; i++){ document.write('i = ' + i + '<br>'); } for(var i=0; i<9; i++){ document.write('i = ' + i + '<br>'); } 

这似乎是有效的(当我testing没有错误)。 看来你可以重新声明JavaScript的variables – 但它可能不是每个好主意,除非特殊情况 – 看到这个相关的问题提及[Google Analytics(分析)如何使用'安全'重新声明的variables]( 重新声明一个JavaScriptvariables )

有一些关于在这个相关的SO问题中重新声明JSvariables(以及像i这样的循环variables)的讨论: 在循环内部或外部声明variables

有一个JavaScript模式用于variables的单个声明