"var”;或者没有”;var”;在JavaScript's”;在“;环
"var" or no "var" in JavaScript's "for-in" loop?
用JavaScript编写for-in
循环的正确方法是什么?浏览器不会对我在这里展示的两种方法中的任何一种发出投诉。首先,有一种方法,其中显式声明迭代变量x
:
for (var x in set) {
...
}
另外,这种方法读起来更自然,但对我来说似乎不正确:
for (x in set) {
...
}
使用var
,它会缩小变量的范围,否则变量会查找最近的闭包来搜索var
语句。如果它找不到var
,则它是全局的(如果您处于严格模式using strict
,则全局变量会抛出错误(。这可能会导致以下问题。
function f (){
for (i=0; i<5; i++);
}
var i = 2;
f ();
alert (i); //i == 5. i should be 2
如果在for循环中写入var i
,则警报将显示2
。
JavaScript范围界定和提升
第一个版本:
for (var x in set) {
...
}
声明了一个名为x
的局部变量。第二个版本:
for (x in set) {
...
}
没有。
如果x
已经是一个局部变量(即,您在当前范围(即当前函数(的较早位置有一个var x;
或var x = ...;
(,那么它们将是等效的。如果x
还不是局部变量,那么使用第二个将隐式声明全局变量x
。考虑这个代码:
var obj1 = {hey: 10, there: 15};
var obj2 = {heli: 99, copter: 10};
function loop1() {
for (x in obj1) alert(x);
}
function loop2() {
for (x in obj2) {
loop1();
alert(x);
}
}
loop2();
您可能希望这会提醒hey
、there
、heli
、hey
、there
、copter
,但由于x
是同一个,它将提醒hey
、there
、there
、hey
、there
、there
。你不想那样!在for
循环中使用var x
。
最重要的是:如果for
循环在全局作用域中(即不在函数中(,则本地作用域(如果使用var x
,则在中声明作用域x
(与全局作用域(使用不带var的x
,则在中隐式声明作用域x
(相同,因此两个版本将相同。
您确实应该用var
声明局部变量,始终。
你也不应该使用"for…in"循环,除非你绝对确定这就是你想要做的。对于在真实数组中迭代(这很常见(,你应该总是使用一个带数字索引的循环:
for (var i = 0; i < array.length; ++i) {
var element = array[i];
// ...
}
在带有"for…in"的普通数组中循环可能会产生意想不到的结果,因为循环可能会拾取数组中除数字索引之外的属性。
编辑—在2015年,使用.forEach()
迭代数组也是可以的:
array.forEach(function(arrayElement, index, array) {
// first parameter is an element of the array
// second parameter is the index of the element in the array
// third parameter is the array itself
...
});
.forEach()
方法出现在IE9前向的Array原型上。
实际上,如果您不喜欢for
标题中的声明,您可以执行以下操作:
var x;
for (x in set) {
...
}
正如这个问题的其他答案中所提到的,根本不使用var
会产生不必要的副作用,比如分配全局属性。
使用声明循环变量var
的方法。隐含声明的变量具有不同的作用域,这可能不是您想要的。
for(var i = 0; ...)
是一种常见的模式,但它与不同
for(int i; ...)
在C++中,变量的作用域不是CCD_ 41块。事实上,var
被提升到封闭作用域(函数(的顶部,因此本地i
在for
循环之前(在当前作用域/函数开始之后(和之后都将有效可用
换句话说,做:
(function(){ //beginning of your current scope;
//...
for(var i in obj) { ... };
})();
与相同
(function(){ //beginning of your current scope;
var i;
//...
for(i in obj) { ... };
})();
ES6使用let
关键字(而不是var
(将作用域限制为for块。
当然,应该使用局部变量(用var
、let
或const
(在ES6中(声明的变量(,而不是隐式全局变量。
如果使用"use strict";
(应该使用(并且未声明i
,则for(i=0; ...)
或for(i in ...)
将失败。
使用var
是最干净的方法,但两者的工作方式如下所述:https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in
基本上,通过使用var
,您可以确保创建一个新的变量。否则,您可能会意外地使用以前定义的变量。
我认为var是好的,因为性能原因。
Javascript不会查看整个全局范围来查看x是否已经存在于其他地方。
从一般的角度来看,第一个版本将用于必须位于循环范围内的索引,而另一个版本将是调用循环构造函数的范围中的任何变量。
如果您要在for循环内部使用循环的索引,而其他人在接下来的行中不需要这样做,那么最好用"var"声明变量,这样您就可以确保"x"是用0初始化的for循环索引,而另一个,如果其他"x"变量在该上下文中可用,则它将被循环的索引覆盖-也就是说,您会有一些逻辑错误-。
我总是使用ES2015中引入的块范围的let
。
for (let x in set) {
...
}
附加阅读和示例
- 控制台返回var不是't定义,但它是
- 从var向代码隐藏函数传递值
- 如何通过引用var Using DataTables来进行分页或排序
- 铬:“;未捕获的语法错误:意外的标记:"
- jQuery语法添加了var
- 如何将具有文本类型值的var放入jQuery函数中
- 可以设置“;文件名"发生错误时显示的内联脚本标记的
- JavaScript美学:;函数foo(){}"vs“;var foo=函数(){}"AMD功能
- 关于变量分配的澄清"var x=!0〃;
- 为什么var c=“;a“||"b”;返回c=“;a“;并且var c=“0”;a“&&"
- 编写一个javascript var="一些文本“;转换为预加载但为空的txt文档
- 什么是“;var对话框={}"jQuery/javascript中的平均值
- var imgLoader = document.getElementById("imgLoader"
- 什么是“||"在var语句中是mean
- 使用逗号初始化/设置多个变量,不带“var"”
- 这是什么样的javascript语法:"var XX=(函数(){..})()"以及如何将其与Typ
- "var canvas=document.getElementById(“canvas”);可以't不
- 它是如何工作的这个javascript"var ApplicationConfig={quot;
- 为什么JS代码"var a=document.querySelector('a[data-a=1]
- "var”;或者没有”;var”;在JavaScript's”;在“;环