Начиная с ES2015, порядок свойств гарантирован для определенных методов, которые перебирают свойства. но не другие . К сожалению, методы, порядок которых не гарантирован, обычно используются чаще всего:
Object.keys
, Object.values
,Object.entries
for..in
петли
JSON.stringify
Но, начиная с ES2020, порядок свойств для этих ранее ненадежных методов будет гарантирован, что спецификация будет повторяться таким же детерминированным образом, как и другие, из-за готового предложения: механика for-in .
Как и в случае с методами, которые имеют гарантированный порядок итераций (например, Reflect.ownKeys
и Object.getOwnPropertyNames
), ранее неуказанные методы также будут выполнять итерацию в следующем порядке:
- Ключи числового массива в порядке возрастания номеров
- Все остальные не символьные ключи, в порядке вставки
- Символьные клавиши, в порядке вставки
Это то, что в значительной степени каждая реализация уже делает (и делала в течение многих лет), но новое предложение сделало его официальным.
Хотя текущая спецификация оставляет для… в итерационном порядке « почти полностью неопределенные , реальные движки имеют тенденцию быть более последовательными:»
Отсутствие специфичности в ECMA-262 не отражает реальность. В ходе дискуссий, которые велись годами, разработчики заметили, что существуют некоторые ограничения на поведение for-in, которым должен следовать любой, кто хочет запускать код в сети.
Поскольку каждая реализация уже предсказуемо перебирает свойства, ее можно поместить в спецификацию, не нарушая обратной совместимости.
Есть несколько странных случаев, с которыми реализации в настоящее время не согласуются, и в таких случаях результирующий порядок будет по-прежнему не определен. Для гарантированного заказа недвижимости :
Ни итерируемый объект, ни что-либо в его цепочке прототипов не являются прокси, типизированным массивом, объектом пространства имен модуля или экзотическим объектом хоста.
Ни у объекта, ни у чего-либо в его цепочке прототипов нет изменений прототипа во время итерации.
Ни у объекта, ни у чего-либо в его цепочке прототипов нет свойства, удаленного во время итерации.
Ничто в цепочке прототипов объекта не имеет свойства, добавленного во время итерации.
Ни одно свойство объекта или чего-либо в его цепочке прототипов не может изменить свою перечислимость во время итерации.
Ни одно не перечислимое свойство не затеняет перечислимое.