Javascript 中的奇怪行为增强了 for...in 循环

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1885317/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 21:45:00  来源:igfitidea点击:

Strange behavior in Javascript enhanced for...in loop

javascriptfor-loopforeach

提问by Spencer

I am making a Javascript game with the canvas tag, and I am using an enhanced for loop to update the player positions.

我正在制作带有 canvas 标签的 Javascript 游戏,并且我正在使用增强的 for 循环来更新玩家位置。

In brief:

简单来说:

var actors = new Array();

var player = new Actor(0, 0, img);

actors[0] = player;

function update_positions() {
    //position 1
    for(var a in actors) {
        //position2
        a.xpos += a.xvel;
        a.ypos += a.yvel;
    }
}

Just outside of the for loop at position 1, I can access the correct value of actors[0].xvel. Inside the for loop at position 2, a.xvel is undefined. Can someone explain to me what is happening?

就在位置 1 的 for 循环之外,我可以访问 actor[0].xvel 的正确值。在位置 2 的 for 循环内, a.xvel 未定义。有人可以向我解释发生了什么吗?

回答by CMS

The for...instatement is meant to be used to iterate over object properties, by looking your code seems that actorsis an Array (you are setting the initial element with index 0).

for...in语句旨在用于迭代对象属性,通过查看您的代码似乎actors是一个数组(您正在使用 index 设置初始元素0)。

This statement will also crawl upthe prototype chain, if you have extended the Array.prototypethose properties will be iterated, and also the order of iteration is not warranted.

这个语句也会爬上原型链,如果你扩展了Array.prototype那些属性会被迭代,并且迭代的顺序也没有保证。

I would recommend you to avoid problemsand iterate using a normal for loop:

我建议您避免出现问题并使用正常的 for 循环进行迭代:

for (var i = 0; i < actors.length; i++) {
    actors[i].xpos += actor.xvel;
    actors[i].ypos += actor.yvel;
}

If I'm wrong, and actorsis not an Array, I would recommend you to use the hasOwnPropertymethod, to ensure that the property exists in the object itself, not up somewhere in the prototype chain:

如果我错了,并且actors不是数组,我会建议您使用该hasOwnProperty方法,以确保该属性存在于对象本身中,而不是在原型链中的某个位置:

for (var name in object) {
  if (object.hasOwnProperty(name)) {
    //
  }
}

回答by am9u

it looks like you're trying to access object properties on the name, not the value here. the index, in this case '0', gets assigned to 'a' in the for/in loop.

看起来您正在尝试访问名称上的对象属性,而不是此处的值。在 for/in 循环中,索引(在本例中为“0”)被分配给“a”。

what you want to do is access the value of the array member, ie: actors[a].

您想要做的是访问数组成员的值,即:actors[a]。

try this:

尝试这个:

for(var a in actors) { // a=0 the first time around the loop,  
    actor = actors[a]; // same thing as actors[0];
    actor.xpos += actor.xvel;
    actor.ypos += actor.yvel;
}

回答by harto

The for (x in y)construct iterates through the indexes of an array, not its members.

for (x in y)构造遍历数组的索引,而不是其成员。

回答by Chris Fulstow

Try using actors[a].xposinstead of just a.xpos.

尝试使用actors[a].xpos而不仅仅是a.xpos.

See here for more info on JavaScript for-in loops.

有关JavaScript for-in 循环的更多信息,请参见此处。

回答by Eamonn O'Brien-Strain

Another option is to use the underscorelibrary:

另一种选择是使用下划线库:

_.each( actors, function(a) {
    a.xpos += a.xvel;
    a.ypos += a.yvel;
});

or if you don't want to use underscore but are using JQuery anyway, then you can do:

或者如果您不想使用下划线但无论如何都在使用 JQuery,那么您可以这样做:

$.each( actors, function(i, a) {
    a.xpos += a.xvel;
    a.ypos += a.yvel;
});

One nice feature of this functional pattern of iteration is that you can use varto declare variables in the loop that are scoped to the body of the loop, which helps avoid getting bitten by the odd variable scoping rules of JavaScript.

这种函数式迭代模式的一个很好的特性是,您可以使用var在循环中声明作用域为循环体的变量,这有助于避免被 JavaScript 的奇怪变量作用域规则所困扰。