Порядок перебора объекта может быть нарушен только во время итерации?

Я предполагаю, что предпочтительный способ перебора объекта следующий:

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

MDN говорит, что

Удаленные, добавленные или измененные свойства. Цикл for ... in выполняет итерацию по свойствам объекта в произвольном порядке (см. оператор удаления, чтобы узнать, почему нельзя полагаться на о кажущейся упорядоченности итераций, по крайней мере, в настройке кроссбраузерности).

Итак, если я не изменяю свойства объекта во время итерации, мне может быть гарантирован правильный порядок, то есть порядок, в котором ключи / свойства появляются в объекте, или этот оператор означает что-то еще?


person Marina Dunst    schedule 20.02.2016    source источник
comment
Нет правильного порядка. Не следует полагаться на порядок собственности.   -  person Pointy    schedule 20.02.2016
comment
Значит, нет возможности гарантировать порядок при просмотре объекта?   -  person Marina Dunst    schedule 20.02.2016
comment
Вы можете использовать Object.keys() для извлечения имен свойств, а затем наложить свой собственный порядок, отсортировав список (или как хотите). Свойства по своей сути не имеют упорядочивания.   -  person Pointy    schedule 20.02.2016
comment
Свойства по своей сути не имеют упорядочивания. ах, вот почему. Спасибо   -  person Marina Dunst    schedule 20.02.2016
comment
В нем говорится, что см. Оператор удаления, и если вы перейдите по ссылке, в ней говорится: все основные браузеры поддерживают порядок итераций на основе самого раннего добавленного свойства, которое будет первым ... Однако в случае Internet Explorer (неприятные вещи ...)   -  person georg    schedule 20.02.2016
comment
@georg Спасибо, я остановился на Спецификациях и подумал, что это конец страницы, надо было прокрутить дальше.   -  person Marina Dunst    schedule 20.02.2016
comment
@MarinaDunst: Я добавил свои выводы в качестве ответа.   -  person georg    schedule 20.02.2016
comment
@Pointy: это больше не верно для ES6 (в отличие от ES5), см. Мой пост.   -  person georg    schedule 20.02.2016


Ответы (1)


Страница при удалении говорится, что:

... все основные браузеры поддерживают порядок итераций, основанный на том, что самое раннее добавленное свойство будет первым ... Однако в случае 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 требует повторения свойств в порядке создания:

Для каждого собственного ключа свойства P из O, который является строкой, но не является целочисленным индексом, в порядке создания свойства ...

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

В стандарте не очень ясно, что именно означает «порядок создания». MS считает, что имеет значение начальное время создания, в то время как другие используют последнее время создания.

person georg    schedule 20.02.2016
comment
Это хороший аргумент в пользу ES5 и ES6. Я в основном использую NodeJS, и они хорошо умеют включать ES6 в максимально возможной степени по сравнению с браузерами. - person Marina Dunst; 20.02.2016