“var”或没有“var” JavaScript 中的“for-in”环形?

发布于 2024-11-02 17:05:51 字数 249 浏览 4 评论 0原文

在 JavaScript 中编写 for-in 循环的正确方法是什么?浏览器不会对我在此处展示的两种方法中的任何一种发出投诉。首先,有一种方法,其中显式声明迭代变量 x :

for (var x in set) {
    ...
}

或者这种方法读起来更自然,但对我来说似乎不正确:

for (x in set) {
    ...
}

What's the correct way to write a for-in loop in JavaScript? The browser doesn't issue a complaint about either of the two approaches I show here. First, there is this approach where the iteration variable x is explicitly declared:

for (var x in set) {
    ...
}

And alternatively this approach which reads more naturally but doesn't seem correct to me:

for (x in set) {
    ...
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

野却迷人 2024-11-09 17:05:51

使用 var,它会缩小变量的范围,否则变量会查找最近的闭包来搜索 var 语句。如果它找不到var,那么它是全局的(如果您处于严格模式,使用严格,全局变量会抛出错误)。这可能会导致如下问题。

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 作用域和提升

Use var, it reduces the scope of the variable otherwise the variable looks up to the nearest closure searching for a var statement. If it cannot find a var then it is global (if you are in a strict mode, using strict, global variables throw an error). This can lead to problems like the following.

function f (){
    for (i=0; i<5; i++);
}
var i = 2;
f ();
alert (i); //i == 5. i should be 2

If you write var i in the for loop the alert shows 2.

JavaScript Scoping and Hoisting

删除→记忆 2024-11-09 17:05:51

第一个版本:

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();

您可能希望它提醒 heythereheliheytherecopter,但由于 x 是同一个,因此它会提醒 heythere那里那里那里。你不想要这样!在 for 循环中使用 var x

最重要的是:如果 for 循环位于全局范围内(即不在函数中),则局部范围(范围 x 被声明,如果您use var x) 与全局作用域相同(如果使用不带 var 的 x,则隐式声明作用域 x),因此这两个版本将是相同的。

The first version:

for (var x in set) {
    ...
}

declares a local variable called x. The second version:

for (x in set) {
    ...
}

does not.

If x is already a local variable (i.e. you have a var x; or var x = ...; somewhere earlier in your current scope (i.e. the current function)) then they will be equivalent. If x is not already a local variable, then using the second will implicitly declare a global variable x. Consider this code:

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();

you might expect this to alert hey, there, heli, hey, there, copter, but since the x is one and the same it will alert hey, there, there, hey, there, there. You don't want that! Use var x in your for loops.

To top it all off: if the for loop is in the global scope (i.e. not in a function), then the local scope (the scope x is declared in if you use var x) is the same as the global scope (the scope x is implicitly declared in if you use x without a var), so the two versions will be identical.

梓梦 2024-11-09 17:05:51

您确实应该使用 varalways 声明局部变量。

您也不应该使用“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 原型。

You really should declare local variables with var, always.

You also should not use "for ... in" loops unless you're absolutely sure that that's what you want to do. For iterating through real arrays (which is pretty common), you should always use a loop with a numeric index:

for (var i = 0; i < array.length; ++i) {
  var element = array[i];
  // ...
}

Iterating through a plain array with "for ... in" can have unexpected consequences, because your loop may pick up attributes of the array besides the numerically indexed ones.

edit — here in 2015 it's also fine to use .forEach() to iterate through an array:

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
  ...
});

The .forEach() method is present on the Array prototype from IE9 forward.

離人涙 2024-11-09 17:05:51

实际上,如果您不喜欢 for 标题中的声明,您可以这样做:

var x;
for (x in set) {
    ...
}

正如该问题的其他答案中提到的,根本不使用 var 会产生不必要的副作用,例如分配全球财产。

Actually, if you dislike declaration within for heading, you can do:

var x;
for (x in set) {
    ...
}

As mentioned in other answers to this question, not using var at all produces unnecessary side-effects like assigning a global property.

满身野味 2024-11-09 17:05:51

使用通过 var 声明循环变量的变量。隐式声明的变量具有不同的范围,这可能不是您想要的。

Use the one where you declare the loop variable with var. Implicitly declared variables have a different scope that's probably not what you intended.

迷鸟归林 2024-11-09 17:05:51
for(var i = 0; ...)

是一种常见的模式,但它与

for(int i; ...)

C++ 中的不同之处在于变量的作用域不限于 for 块。事实上,var 被提升到封闭范围(函数)的顶部,因此本地 i 将在 for 之前有效地可用循环(在当前作用域/函数开始之后)及其之后。

换句话说,doing:

(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 块的范围。

当然,您应该使用局部变量(使用 varletconst (在 ES6 中)声明的变量)而不是隐式全局变量。

如果您使用 "use strict";for(i=0; ...)for(i in ...) 将失败(正如您应该的那样)并且未声明 i

for(var i = 0; ...)

is a commonly seen pattern but it's different from

for(int i; ...)

in C++ in that that the variable isn't scoped to the for block. In fact, the var gets hoisted to the top of the enclosing scope (function) so a local i will be effectively available both before the for loop (after the beginning of the current scope/function) and after it.

In other words, doing:

(function(){ //beginning of your current scope;
 //...
 for(var i in obj) { ... };
})();

is the same as:

(function(){ //beginning of your current scope;
 var i;
 //...
 for(i in obj) { ... };
})();

ES6 has the let keyword (instead of var) to limit the scope to the for block.

Of course, you SHOULD be using local variables (ones declared with either var or let or const (in ES6)) rather than implicit globals.

for(i=0; ...) or for(i in ...) will fail if you use "use strict"; (as you should) and i isn't declared.

顾铮苏瑾 2024-11-09 17:05:51

使用 var 是最简洁的方法,但两者的工作原理如下:https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in

基本上,通过使用 var 您可以确保创建一个新变量。否则您可能会意外使用先前定义的变量。

Using var is the cleanest way, but both work as described here: https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in

Basically, by using var you ensure that you create a new variable. Otherwise you might accidentally use a previously defined variable.

是伱的 2024-11-09 17:05:51

我认为 var 出于性能原因很好。

JavaScript 不会遍历整个全局范围来查看 x 是否已经存在于其他地方。

I think var is good for performance reasons.

Javascript won't look through the whole global scope to see if x already exists somewhere else.

九歌凝 2024-11-09 17:05:51

从一般角度来看,第一个版本将用于必须位于循环范围内的索引,而另一个版本将是调用循环构造函数的范围中的任何变量。

如果您要在 for 循环内使用循环索引,并且下一行中的其他人不需要这样做,最好使用“var”声明变量,这样您就可以确保“x”是用 0 初始化的 for 循环索引,而另一个,如果其他“x”变量在此上下文中可用,则这将被循环的索引覆盖 - 这就是你会遇到一些逻辑错误 - 。

From a general point of view, first version will be for an index that must live within loop's scope, while the other one would be any variable in the scope where loop's constructor got invoked.

If you're going to use loop's index inside for loop and this won't be required by others in next lines, better declare the variable with "var" so you'll be sure "x" is for loop's index initialized with 0, while the other one, if other "x" variable is available in this context, this will get overwritten by loop's index - that's you'll have some logical errors -.

煞人兵器 2024-11-09 17:05:51

我总是使用 ES2015 中引入的块作用域 let

for (let x in set) {
    ...
}

其他阅读材料和示例

I always use the block scoped let introduced in ES2015.

for (let x in set) {
    ...
}

Additional reading and examples

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文