【问题标题】:javascript access the counter of a for in loopjavascript访问for in循环的计数器
【发布时间】:2014-06-01 15:50:08
【问题描述】:

如何访问 for..in 循环的计数器?

我有一个数组和一个对象。我想在对数组执行相同操作的同时迭代对象属性,而不显式声明计数器。

var colors = ['red','yellow','purple','blue'];

var flowers = {'rose':'','sunflower':'','violet':'','hydrangea':''};

for (prop in flowers) {
    flowers[prop] = colors[i];
}

跟进问题。如果不可能,我将如何使用我需要的功能创建自己的 for 循环。以下是它目前的工作方式,但我发现我经常这样做并且想要创建可重用的东西。

var colors = ['red','yellow','purple','blue'];

var flowers = {'rose':'','sunflower':'','violet':'','hydrangea':''};

var i = 0;
for (prop in flowers) {
    flowers[prop] = colors[i];
    i++;
}

【问题讨论】:

  • @DanielA.White 我已经改写了这个问题。
  • 你只需要属性的索引吗?因为那真的不存在
  • 是的,为什么你对我的问题投了反对票?
  • @T.J.Crowder 没错,假设确实倾向于使...你知道的。注意到。
  • @toddsby xkcd.com/1339

标签: javascript loops iterator


【解决方案1】:

(ECMAScript 2015 改变了一些东西,请参阅答案末尾的更新。)

我有一个数组和一个对象。我想在对数组执行相同操作的同时迭代对象属性,而不显式声明计数器。

我不相信你可以。此外,了解对象中的属性没有顺序也很重要。您似乎假设您会得到“玫瑰”,然后是“向日葵”等。这根本无法保证。许多引擎按照属性添加到对象的顺序访问对象属性名称,而现在将对象初始值设定项中的文字属性添加到对象的顺序是(从 ES5 开始,一对多年前)已指定,但以for-in 中的任何特定顺序访问它们不是指定的行为(同样,Object.keys 未以任何特定方式排序),并且完全正确的引擎可以以任何它想要的顺序访问它们。

因此,仅使用您显示的数组和对象,您没有可靠的方法将这些属性映射到数组条目。


从 ECMAScript 2015 (ES6) 开始,对象属性have order now

  1. keys 成为一个新的空列表。
  2. 对于作为整数索引的 O 的每个自己的属性键 P,按数字索引升序排列
    • 添加P作为keys的最后一个元素。
  3. 对于 O 的每个自己的属性键 P,它是一个字符串但不是整数索引,按属性创建顺序
    • 添加P作为keys的最后一个元素。
  4. 对于作为符号的 O 的每个自己的属性键 P,按属性创建顺序
    • 添加P作为keys的最后一个元素。
  5. 返回

好的,所以我们知道它们将按“创建”顺序被访问,但是对象初始化程序以什么顺序创建它们?好消息:Object initializers源代码顺序处理,所以这是确定性的。您的rose 位于您的sunflower 之前,等等。

这意味着,如果不显式声明和维护索引变量,您仍然无法做您想做的事情,但您可以可靠地关联该数组和该对象:

// Works as of ES6
var colors = ['red','yellow','purple','blue'];

var flowers = {'rose':'','sunflower':'','violet':'','hydrangea':''};

let i = 0;
for (prop in flowers) {
    flowers[prop] = colors[i++];
}

我不建议这样做,但现在可以在兼容的引擎上使用。

【讨论】:

  • 在内部,for in 循环不使用迭代器,或者这也是一个糟糕的假设?我的想法是,如果循环使用的是迭代器,我可以从 for 循环内部访问它。
  • @toddsby:The current spec just says 引擎应该创建一个列表,并且循环执行“next”属性直到完成,而不指定其机制。 ES6 草案根据迭代器定义了算法,但是属性仍然没有顺序(呃,除非他们在某处添加了它),所以即使 ES6 根据迭代器定义它,即使它允许您访问迭代器,您仍然不能假设您访问的第一个属性将是“玫瑰”。
  • 如何创建一个具有我需要的功能的 for 循环? (见更新的问题)
  • @toddsby:正如我上面所说:你不能。 flowers 对象没有顺序,因此不可能按位置关联flowers 对象的属性。 (旁注:我检查过,14 年 4 月的 ES6 草案在 §9.1.11 中清楚地说明了这些属性仍然没有顺序,所以当我不看的时候,他们没有把它滑到 ES6 中。:-)有一个五月的草稿,我现在没有时间下载和检查,但我怀疑他们已经改变了。)
  • 感谢您为我指明了正确的方向。我没有理解 enumeration and iteration 在 javascript 如何处理 for in 循环方面的区别。我还在这里找到了一个可能的解决方案:How to keep Javascript object/array ordered while also maintaining key lookups
猜你喜欢
  • 2011-10-21
  • 2011-07-12
  • 2020-05-31
  • 2015-02-25
  • 1970-01-01
  • 2013-10-29
  • 1970-01-01
  • 2016-03-30
  • 2012-11-18
相关资源
最近更新 更多