1. 程式人生 > >JavaScript --Map和Set, Iterable

JavaScript --Map和Set, Iterable

Map

Map是一組鍵值對的結構,具有極快的查詢速度。比如,要根據同學的名字查詢對應的成績,我們用Map實現,只需要一個“名字“ - ”成績“的對照表,直接根據名字查詢成績,無論這個表多大,查詢速度都不會變慢。用JavaScript寫一個Map:
var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.get('Michael');

從而直接得到Michael的成績95了,初始化Map需要一個二維陣列,或者直接初始化一個空Map,Map具有以下的方法:
var m = new Map(); //空Map
m.set('Adam', 67);	//新增新的key-value
m.set('Bob', 59);
m.has('Adam');	//是否存在key 'Adam': true
m.get('Adam');	67
m.delete('Adam');	//刪除key 'Adam'
m.get('Adam');

而由於一個key只能對應一個value,所以,多次對一個key放入value,後面的值會把前面的值沖掉。

Set

Set和Map類似,也是一組key的集合,但不儲存value。由於key不能重複,所以在Set中,沒有重複的key。要建立一個Set,需要提供一個Array作為輸入,或者直接建立一個空的Set:
var s1 = new Set();	// 空Set
var s2 = new Set([1, 2, 3]); // 含1, 2, 3
var s = new Set([1, 2, 3, 3, '3']);
s;	// Set {1, 2, 3, '3'}

Set具有以下函式: 1. add(key)方法可以新增元素到Set中,可以重複新增,但不會有效果。
>>> s.add(4)
>>> s
{1, 2, 3, 4}
>>> s.add(4)
>>> s
{1, 2, 3, 4}

2. delete(key)方法可以刪除元素:
var s = new Set([1, 2, 3]);
s; // Set {1, 2, 3}
s.delete(3);
s; // Set {1, 2}

Map和Set是ES6標準的新增的資料型別,要確保瀏覽器支援使用。

Iterable

遍歷Array可以使用下標迴圈,遍歷Map和Set就無法使用下標。為了統一集合型別,ES6標準引入了新的iterable型別,Array、Map和Set都屬於iterable型別。具有iterable型別的集合都可以通過新的for ... of迴圈來遍歷。 for ... of迴圈是ES6引入的新的語法,例如:
'use strict';
var a = [1, 2, 3];
for(var x of a) {

}

用for ... of 迴圈遍歷集合,用法很簡單,例子如下:
var a = ['A', 'B', 'C'];
var s = new Set(['A', 'B', 'C']);
var m = new Map([1, 'x'], [2, 'y'], [3, 'z']);
for(var x of a) {
	alert(x);
}

for(var x of s) {
	alert(x);
}

for(var x of m) {
	alert(x[0] + '=' + x[1]);
}

for...in 迴圈遍歷的實際是物件的屬性名稱。一個Array陣列實際上也是一個物件,它的每個元素的索引被稱為一個屬性。例如
var a = ['A', 'B', 'C'];
a.name = 'Hello';
for(var x in a) {
	alert(x);  // '0', '1', '2', 'name'
}

for ... in 迴圈將把name包含在內,但Array的length屬性不包含在內。 for ... of 迴圈只迴圈集合本身的元素:
var a = ['A', 'B', 'C'];
a.name = 'Hello';
for(var x of a) {
	alert(x);	// 'A', 'B', 'C'
}


更好的方式是直接是使用iterable內建的forEach方法,它接收一個函式,每次迭代都自動回撥該函式。以Array為例:
var a = ['A', 'B', 'C'];
a.forEach(function (element, index, array)) {
	//element: 指向當前元素的值
	//index: 指向當前索引
	//array: 指向Array物件本身
	alert(element);
});

Set與Array類似,但Set沒有索引
var s = new Set(['A', 'B', 'C']);
s.forEach(function (element, sameElement, set) {
    alert(element);
});

Map的回撥函式引數依次為value, key, map本身:
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
m.forEach(function (value, key, map) {
    alert(value);
});

當然,由於JavaScript的函式呼叫不要求引數必須一致,因此可以忽略它們。
var a = ['A', 'B', 'C'];
a.forEach(function (element) {
    alert(element);
});