在ES6中對象屬性的順序是可預測的

常見的誤解–“無法保證JavaScript屬性的順序”:幾年前開始編寫JavaScript時,您可能已經聽說過JS對象中屬性的順序是不可預測的。我從來沒有碰到過奇怪和不尋常的屬性順序,但是我始終遵循從不依賴屬性順序的原則。

內部ownPropertyKeys方法

事實上,自ES6起,有一些方法基於定義屬性順序的特定規則,除了一種特殊情況外,該順序是按時間順序排列的,並依賴於對象屬性的類型和值。

這些規則被定義在 the inernal “ownProertyKes” method 規範中。例如,es6中新的函數Object.getOwnPropertyNamesReflect.ownKeys已經使用了這些規則。

這個規則引起了一些有趣的變化,例如Object.keysES5ES6的規則發生了變化。ES6規範規定Object.keys也依賴於ownPropertyKeys,這樣就使得Object.keys在現代瀏覽器中的執行結果也是可預測。

但是,這也意味着您必須謹慎使用此方法,並且不應依賴於可預測的順序使用Object.keys,因爲Object.keys的執行結果可能會因瀏覽器的實現而有所不同

但是已經有足夠多的理由,讓我們去了解ownPropertyKeys是如何定義的屬性順序的。

1.整數指數

所有爲整數索引的屬性均按整體對象屬性順序顯示在第一位,並按數字升序排列。

const objWithIndices = {
  23: 23,
  '1': 1,
  1000: 1000
};

console.log(Reflect.ownKeys(objWithIndices));
// [1, 23, 1000]
// ☝️ following numeric order

2.字符串(不是整數)

屬性既不是整數索引,也不是Symbol類型的,按照添加的時間順序排列。

const objWithStrings = {
  'bar': 'bar',
  '01': '01'
};

objWithStrings.last = 'last';
objWithStrings['veryLast'] = 'veryLast';

console.log(Reflect.ownKeys(objWithStrings));
// ['bar', '01', 'last', 'veryLast']
// ☝️ following chronological order

3.Symbol

最後,Symbol也按照時間順序排列。

const objWithSymbols = {
  [Symbol('first')]: 'first',
  [Symbol('second')]: 'second'
};

objWithSymbols[Symbol('last')] = 'last';

console.log(Reflect.ownKeys(objWithSymbols));
// [Symbol(first), Symbol(second), Symbol(last)]
// ☝️ following chronological order

三種類型一起

將三種類型的屬性放在一起時,整數始終位於對象屬性的“第一行”中,其後是字符串和Symbol此外,我們可以控制字符串和Symbol屬性的順序,因爲它們是按添加的時間順序排列!

const obj = {
  '2': 'integer: 2',
  'foo': 'string: foo',
  '01': 'string: 01',
  1: 'integer: 1',
  [Symbol('first')]: 'symbol: first'
};

obj['0'] = '0';
obj[Symbol('last')] = 'symbol: last';
obj['veryLast'] = 'string: very last';

console.log(Reflect.ownKeys(obj));
// [ "0", "1", "2", "foo", "01", "veryLast", Symbol(first), Symbol(last) ]
// -> 1. integers in numeric order
// -> 2. strings in chronological order
// -> 3. Symbols in chronological order

編輯:正如Malgosia Stepniak所指出的那樣,僅現代瀏覽器完全支持 “own property order” ,而IE則不完全支持。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章