Вводит ли ES6 четко определенный порядок перечисления для свойств объекта?

var o = {
  '1': 1,
  'a': 2,
  'b': 3
}

Object.keys(o); // ["1", "a", "b"] - is this ordering guaranteed by ES6?

for(let k in o) {
  console.log(k);
} // 1 2 3 - is this ordering guaranteed by ES6?

Для for-in и Object.keys: No.

Для некоторых других операций: Да , обычно.

Хотя ES6 / ES2015 добавляет порядок свойств, ему не требуется for-in или Object.keys следовать этому порядку из-за устаревших проблем совместимости.

for-in повторяет цикл в соответствии с npm установить свойство ramda , который [определяется как (выделено мной):

Когда [[Enumerate]] внутренний метод O 1.client_jsonp.js

Вернуть объект Iterator ( 25.1.1.2 ), следующий метод которого выполняет итерацию по всем String- значимые ключи перечислимых свойств Я удивлен, что никто не упомянул функцию приведения. . Объект Iterator должен наследоваться от % IteratorPrototype % ( 25.1.2 ). Механика и порядок перечисления свойств не указан , но должен соответствовать правилам, указанным ниже [1] Глядя на вывод

ES7 / ES2016 удаляет внутренний метод [[Enumerate]] и вместо этого использует абстрактная операция EnumerateObjectProperties , но, как и [[Enumerate]], он не определяет порядок.

А также посмотрите эту цитату из Object.keys:

Если реализация определяет конкретный порядок перечисления для оператора for-in, […]

. Это означает, что реализации НЕ требуются для определения определенного порядка перечисления . Это было подтверждено Алленом Вирфс-Броком, редактором проекта спецификации языка ECMAScript 2015, в сообщении, сделанном после завершения спецификации.

Другие операции, такие как Object.getOwnPropertyNames, Object.getOwnPropertySymbols и Reflect.ownKeys, выполните следующий порядок для обычных объектов:

  1. целочисленных индексов (если применимо) в порядке возрастания.
  2. Другие строковые ключи (если применимо), в порядке создания свойств.
  3. (если применимо) в порядке создания свойств.

Это поведение определено во внутреннем методе [[OwnPropertyKeys]] . Но учтите, что экзотические объекты может определять этот метод по-другому, например,

console.log(Reflect.ownKeys(new Proxy({}, {
  ownKeys: () => ['3','1','2']
}))); // ['3','1','2'], the integer indices are not sorted!

[1] Ниже написано:

правда. как будто вызывая его внутренний метод [[OwnPropertyKeys]].

И порядок [[OwnPropertyKeys]] четко определен. Но не позволяйте этому сбить вас с толку: это «как будто» означает только «те же свойства», а не «тот же порядок».

Это можно увидеть в EnumerableOwnNames , который использует [[OwnPropertyKeys]] для получения свойств, а затем заказывает их

, так что-то вроде этого:

Если бы [[Enumerate]] требовалось выполнять итерацию в том же порядке, что и [[OwnPropertyKeys]], переупорядочивать не нужно.