A ordem das propriedades em objetos normais é um assunto complexo em Javascript.
Enquanto no ES5 explicitamente nenhum pedido foi especificado, o ES2015 tem um pedido em determinados casos. Dado é o seguinte objeto:
o = Object.create(null, {
m: {value: function() {}, enumerable: true},
"2": {value: "2", enumerable: true},
"b": {value: "b", enumerable: true},
0: {value: 0, enumerable: true},
[Symbol()]: {value: "sym", enumerable: true},
"1": {value: "1", enumerable: true},
"a": {value: "a", enumerable: true},
});
Isso resulta na seguinte ordem (em certos casos):
Object {
0: 0,
1: "1",
2: "2",
b: "b",
a: "a",
m: function() {},
Symbol(): "sym"
}
- chaves do tipo inteiro em ordem crescente
- chaves normais em ordem de inserção
- Símbolos em ordem de inserção
Portanto, existem três segmentos que podem alterar a ordem de inserção (como aconteceu no exemplo). E chaves do tipo inteiro não se atêm à ordem de inserção.
A questão é: para quais métodos esse pedido é garantido nas especificações do ES2015?
Os métodos a seguir garantem a ordem mostrada:
- Object.assign
- Object.defineProperties
- Object.getOwnPropertyNames
- Object.getOwnPropertySymbols
- Reflect.ownKeys
Os seguintes métodos / loops garantem nenhuma ordem:
- Object.keys
- for..in
- JSON.parse
- JSON.stringify
Conclusão: Mesmo no ES2015, você não deve confiar na ordem das propriedades dos objetos normais em Javascript. É propenso a erros. Use em Map
vez disso.