循环遍历对象的顺序可能只在迭代期间被打破?

The order of looping through an object may be broken only during iteration?

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

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

MDN 说

Deleted, added or modified properties A for...in loop iterates over the properties of an object in an arbitrary order (see the delete operator for more on why one cannot depend on the seeming orderliness of iteration, at least in a cross-browser setting).

因此,如果我在迭代期间不修改对象属性,我可以保证正确的顺序,即 keys/properties 在对象中出现的顺序,或者此语句有其他含义?

MDN page on delete 指出:

...all major browsers support an iteration order based on the earliest added property coming first... However, in the case of Internet Explorer, when one uses delete on a property [and] adds back a property with the same name, the property will be iterated in its old position -- not at the end of the iteration sequence...

插图:

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 要求必须按创建顺序迭代属性:

For each own property key P of O that is a String but is not an integer index, in property creation order...

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

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