Kolejność właściwości w normalnych obiektach jest złożonym tematem w Javascript.
Podczas gdy w ES5 wyraźnie nie określono kolejności, w niektórych przypadkach ES2015 ma zamówienie. Podany jest następujący obiekt:
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},
});
Powoduje to następującą kolejność (w niektórych przypadkach):
Object {
0: 0,
1: "1",
2: "2",
b: "b",
a: "a",
m: function() {},
Symbol(): "sym"
}
- klucze całkowite w porządku rosnącym
- normalne klucze w kolejności wprowadzania
- Symbole w kolejności wstawiania
Istnieją zatem trzy segmenty, które mogą zmienić kolejność wstawiania (jak to miało miejsce w przykładzie). A klucze podobne do liczb całkowitych wcale nie trzymają się kolejności wstawiania.
Pytanie brzmi: dla jakich metod to zamówienie jest gwarantowane w specyfikacji ES2015?
Następujące metody gwarantują pokazaną kolejność:
- Object.assign
- Object.defineProperties
- Object.getOwnPropertyNames
- Object.getOwnPropertySymbols
- Reflect.ownKeys
Następujące metody / pętle nie gwarantują żadnego zamówienia:
- Object.keys
- dla w
- JSON.parse
- JSON.stringify
Wniosek: Nawet w ES2015 nie powinieneś polegać na kolejności właściwości normalnych obiektów w JavaScript. Jest podatny na błędy. Użyj Map
zamiast tego.