索引鍵集合

您可以使用物件常值儲存鍵/值組合,並使用 Array 儲存可疊代的值集合。ES6 也推出了特殊的資料結構,以滿足更精細的用途:對應鍵/值組合,以及為個別值設定。

地圖

「地圖」是可疊代的資料結構,可將資訊儲存為鍵/值組合,類似物件常值。與物件常值不同,Map 允許值和鍵具有任何資料類型,而在地圖的疊代時,會將順序元素保留下來。

如要建立地圖,請使用 Map() 建構函式:

const myMap = new Map();

myMap;
> Map(0)

您可以使用類似陣列 (或任何疊代器物件) 的語法,為地圖預先填入資料,這類語法包含兩個元素組成類似陣列的物件。這兩個元素資料結構中的第一個元素會成為鍵,第二個元素則成為與該鍵相關聯的值。最簡單的方法是使用陣列,其中每個元素本身都是陣列,由兩個元素組成,亦即要新增至地圖的鍵和元素值:

const myMap = new Map([
    [ "myKey", "A string value" ],
    [ "mySecondKey", 500 ],
    [ "myThirdKey", true ]
]);

myMap;
> Map(3) {'myKey' => 'A string value', 'mySecondKey' => 500, 'myThirdKey' => true}

同樣地,地圖物件與物件常值不同,和鍵值皆可接受任何資料類型和值:

const notAFunction = () => console.log( "function" );
const myMap = new Map([
  [ null, 0 ],
  [ false, "This is false" ],
  [ undefined, "No defined value" ],
  [ NaN, "Not a number" ]
]);

myMap;
> Map(4) {null => 0, false => 'This is false', undefined => 'No defined value', NaN => 'Not a number'}

如要取得、設定或刪除地圖元素,請使用從 Map 建構函式沿用的方法:

const myMap = new Map();

myMap;
> Map(0)

myMap.set( "myKey", "My value." );

myMap.has( "myKey" );
> true

myMap.get( "myKey" );
"My value."

myMap.delete( "myKey" );

myMap;
> Map(0)

對應中的鍵不會重複,也就是說,設定相同的鍵會覆寫先前儲存的鍵/值組合:

const myMap = new Map([ [ "myKey", "A string value" ] ]);

myMap.set( "myKey", 500 );

myMap;
> Map(1) {'myKey' => 500}

與物件相同,您可以將地圖指派給使用 const 宣告的變數,然後修改該地圖。然而,如同 const 的其他用途,您無法變更或刪除變數本身:

const myMap = new Map();
myMap.set( "myKey", "A string value" );

myMap;
> Map(1) {'myKey' => 500}

WeakMap

WeakMap 是保留「弱」references的地圖,這些參照必須是尚未加入全域符號註冊資料庫的物件或符號

如要建立 WeakMap,請使用 WeakMap() 建構函式:

const myWeakMap = new WeakMap();

myWeakMap;
> WeakMap(0)

WeakMap 語法與地圖類似,但 WeakMaps 不能可疊代,且嘗試使用物件或符號以外的任何值做為鍵,會導致語法錯誤。當 WeakMap 外沒有金鑰references時,該物件或符號及 WeakMap 中的相關值都可以使用垃圾收集

此做法可允許不同用途,例如將與物件相關聯的中繼資料儲存在 WeakMap 中,並將物件的參照做為鍵。如果這個物件沒有其他參照,且該物件從記憶體中移除,系統也會移除相關聯的中繼資料。

設定

組合是一組可疊代的不重複值,類似於陣列,但集合只能包含「不重複」值。與地圖相同,疊代集合會保留加入的順序元素。

如要建立集合,請使用 Set() 建構函式:

const mySet = new Set();

mySet;
> Set []

您也可以透過陣列常值建立集合:

const mySet = new Set([ 1, 2, 3 ]);

mySet;
> Set(3) [ 1, 2, 3 ]

由於集合不允許使用重複的元素,因此如果集合是從包含相同值的多個例項的陣列建立,它只會保留該值的第一個例項:

const mySet = new Set([ 1, 2, 3, 2 ]);

mySet;
> Set(3) [ 1, 2, 3 ]

如要在集合中新增或移除元素,請使用從 Set 建構函式繼承的方法。這些方法會根據元素本身的值,而非參照索引:

const mySet = new Set();

mySet.add( "My value." );

mySet;
> Set [ "My value." ]

mySet.has( "My value." );
> true

mySet.delete( "My value." );

mySet;
> Set []

雖然集合並未建立索引,且不應用於這類集合,但集合中的元素會「疊代」,以便依序插入。如果嘗試在集合中新增重複的元素值,則系統會略過該值,並保留原始插入順序:

const mySet = new Set([ 1, 2, 3 ]);

mySet;
> Set(3) [ 1, 2, 3 ]

mySet.add( 2 );
> Set(3) [ 1, 2, 3 ]

如要從集合建立陣列,請使用 Array.from() 方法或分散語法:

const mySet = new Set([ 1, 2, 3 ]);
const myArray = Array.from( mySet );

myArray;
> Array(3) [ 1, 2, 3 ]

[ ...mySet ];
> Array(3) [ 1, 2, 3 ]

WeakSet

WeakSet 是僅包含可垃圾收集值的集合 (如對物件的參照,或尚未加入全域符號註冊資料庫的 Symbols)。

如要建立 WeakSet,請使用 WeakSet() 建構函式:

const myWeakSet = new WeakSet();

myWeakSet;
> WeakSet []

WeakSet 語法與 Set 類似,但 WeakSet 無法可疊代,且嘗試新增物件或符號以外的任何值,將會導致語法錯誤。與 WeakMap 一樣,如果沒有 WeakSet 參照的值references,該值就符合垃圾收集的資格。

此做法適用於用途,例如匯總單一相關物件的可疊代集合。如果 WeakSet 參照的物件沒有其他參照,系統也會從 WeakSet 中移除相關元素。

隨堂測驗

請看看下方範例:

        const myMap = new Map([ [ "myKey", "My string" ] ]);
        myMap.set( "myKey", 100 );
      

myMap 會傳回什麼?

100
"My string"
undefined