【问题标题】:The order of looping through an object may be broken only during iteration?遍历对象的顺序可能仅在迭代期间被破坏?
【发布时间】:2016-06-02 05:06:59
【问题描述】:

我猜循环对象的首选方式是这样的:

for (var prop in obj) {
  if( obj.hasOwnProperty( prop ) ) {
    console.log("obj." + prop + " = " + obj[prop]);
  } 
}

MDN 是这么说的

已删除、添加或修改的属性 for...in 循环以 任意顺序 迭代对象的属性(请参阅 delete 运算符了解更多关于为什么不能依赖迭代的表面顺序,至少在交叉浏览器设置)。

因此,如果我在迭代期间不修改对象属性,我可以保证正确的顺序,即键/属性出现在对象中的顺序,或者此语句意味着其他什么?

【问题讨论】:

  • 没有“正确”的顺序。不应依赖财产顺序。
  • 那么循环一个对象时没有办法保证顺序?
  • 您可以使用Object.keys() 提取属性名称,然后通过对列表(或任何您想要的)进行排序来施加您自己的顺序。属性本身没有任何顺序。
  • “属性本身没有任何顺序。”啊,这就是为什么。谢谢
  • 它说“查看删除操作符”,如果你 follow the link 它说:“所有主流浏览器都支持基于最早添加的属性的迭代顺序首先出现......但是,在这种情况下Internet Explorer(讨厌的东西......)”

标签: javascript object iteration for-in-loop


【解决方案1】:

MDN page on delete 声明:

...所有主要浏览器都支持基于最早添加的属性的迭代顺序...但是,在 Internet Explorer 的情况下,当对属性使用 delete [并] 添加回具有相同属性的属性时名称,属性将在其旧位置迭代——而不是在迭代序列的末尾......

插图:

var obj = {};

obj.x = 1; 
obj.y = 2;
obj.z = 3;

var a = [];
for(var i in obj) a.push(i);

delete obj.y;
obj.y = 2;

var b = [];
for(var i in obj) b.push(i);


document.write("1:" + a + "<br>2:" + b);

Chrome/FF/Safari 显示 1:x,y,z 2:x,z,y,而在 MSIE(和 Edge)中,结果是 1:x,y,z 2:x,y,z

请注意,与 ES5 不同,ES6 要求属性必须按创建顺序迭代:

对于 O 的每个自己的属性键 P,它是一个字符串但不是整数索引,按属性创建顺序...

http://www.ecma-international.org/ecma-262/6.0/#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys

标准不是很清楚“创建顺序”到底是什么意思。 MS 认为重要的是 initial 创建时间,而其他人使用 last 创建时间。

【讨论】:

  • 这是 ES5 与 ES6 的一个好点。我主要做 NodeJS,他们擅长将 ES6 与浏览器结合起来。
猜你喜欢
  • 2013-07-29
  • 1970-01-01
  • 2019-02-27
  • 1970-01-01
  • 2017-05-20
  • 1970-01-01
  • 2010-12-25
  • 1970-01-01
相关资源
最近更新 更多