65

只是一个关于 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'打印。

4

5 回答 5

72

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

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

于 2013-08-27T12:22:23.877 回答
60

JavaScript在引入之前没有块作用域const,只是函数作用域。由于 的初始化在一个函数内,因此该变量可以在同一函数的其他任何地方访问。letvari

来自MDN

重要提示:JavaScript 没有块作用域。与块一起引入的变量的作用域是包含函数或脚本,并且设置它们的效果会持续到块本身之外。换句话说,块语句不引入范围。尽管“独立”块是有效的语法,但您不想在 JavaScript 中使用独立块,因为如果您认为它们在 C 或 Java 中执行类似块的操作,它们不会按照您的想法执行。

于 2013-08-27T12:22:42.403 回答
16

javascript 的人正在尝试解决这个问题!

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

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

您可以在此处阅读更多相关信息(特别是,请参阅“for 循环中的 let 范围变量”部分): https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

您可以在此处查看当前浏览器支持(查找行 Bindings -> let): https ://kangax.github.io/compat-table/es6/

于 2016-04-13T18:58:00.563 回答
10

与其他语言(例如:Java、C++、C)不同,JavaScript 不支持块作用域。一旦你在循环或函数中声明了一个变量,如果你这样做,它的范围就在函数体内

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

在这里,您i成为一个全局变量,并j成为循环所在的函数或脚本的本地变量。

于 2014-10-01T06:16:24.587 回答
9
for(i=0; i<arr.length; i++) {
    var j=0;
    // ...
}

说上面创建了一个全局变量是不正确的i。我相信你应该总是使用var来声明变量(除非你故意想要一个“属性”而不是一个“变量”——这在 99.99% 的 JS 编码场景中是不太可能的......)

var在分配初始值时省略i不是创建局部变量,甚至不是全局变量,而是为i全局对象创建一个属性(它可能看起来/行为大多像一个全局变量 - 但它们有一些细微的差异)。

更好的是:

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

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

在什么是 var 关键字变量与 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(分析)如何使用变量的“安全”重新声明](重新声明一个 javascript 变量

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

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

于 2014-10-21T15:59:29.173 回答