ES6入門——Set和Map數據結構

Set

ES6提供了新的數據結構Set。類似於數組,只不過其成員值都是唯一的,沒有重複的值。

Set本身是一個構造函數,用來生成Set數據結構。

var s = new Set();

// 通過add方法向Set結構中加入成員
[2, 3, 5, 4, 5, 2, 2].map(x => s.add(x))

for (i of s) { console.log(i) }
// 2 3 4 5 (表明set結構不會添加重複的值)

Set結構接收一個數組作爲參數,用來初始化。

var items = new Set([1, 2, 3, 4, 5, 5, 5]);

items.size 
// 5

向Set加入值的時候,不會發生類型轉換。這意味着,在Set中5和”5”是兩個不同的值。

Set結構有以下屬性:

  • Set.prototype.constructor: 構造函數,默認就是Set函數。
  • set.prototype.size : 返回Set的成員總數。

Set結構有以下方法:

  • add(value) : 添加某個值。
  • delete(value) : 刪除某個值。
  • has(value) : 返回一個布爾值,表示該值是否爲Set的成員。
  • clear() : 清除所有成員。
s.add(1).add(2).add(2); // 注意“2”被加入了兩次
s.size //2

s.has(1) // true
s.has(2) // true
s.has(3) // false

s.delete(2);
s.has(2)  // false

下面對比以下,看看在判斷是否包括一個鍵上面,對象和Set的寫法有哪些不同。

// 對象寫法
var properties = {
    "width": 1,
    "height": 1
};

if ( properties[someName]) {
    // do something
}

/****************************************/

// Set的寫法
var properties = new Set();

properties.add('width');
peoperties.add('height');

if ( properties.has(someName) ) {
    // do something
}

注意: Array.from方法可以將Set結構轉換爲數組。

var items = new Set([1, 2, 3, 4, 5]);
var array = Array.from( items );

這也提供了一種除去數組中重複元素的方法。

function dedupe( array ) {
    return Array.from( new Set(array) );
}

Map


基本用法

Js對象本質上是鍵值對的集合。但是隻能使用字符串充當鍵。這在一定程度上給我們的使用帶來很大的限制。

var data = {};
var element = document.getElementById("myDiv");

// 將DOM節點(即element)當做對象data的鍵.
// 但是對象只接受字符串作爲鍵名,所以element被自動轉換爲字符串"[Object HTMLDivElement]"
data[element] = metadata;

而ES6正是爲了解決這個問題才提供了Map結構。它類似與對象,也是鍵值對集合,但是”鍵”的範圍不限於字符串,對象也可以當作鍵。

var m = new Map();
o = {p: "hello world"};

m.set(o, "content");
console.log( m.get(o) );  // content

在上面的代碼中,將對象o當作m的一個鍵。

Map函數可接收一個數組進行初始化。

var map = new Map([["name", "小明"], ["title", "Author"]]);

map.size //2
map.has("name"); //true
map.get("name"); //小明
map.has("title"); //true
map.get("title"); //Author

注意:只有針對同一個對象的引用,Map結構纔將其視作同一個鍵。這一點要非常小心纔行。

var map = new Map();

map.set(['a'], 555);
map.get(['a']);  // undefined

上面代碼中set和get方法表面上是針對同一個鍵,但實際上這是兩個值,內存地址是不一樣的,因此get方法無法讀取該鍵,返回undefined。

再看看下面一段代碼:

var map = new Map();

var k1 = ['a'];
var k2 = ['a'];

map.set(k1, 111);
map.set(k2, 222);

map.get( k1 );  //111
map.get( k2 );  //222

上面代碼,變量k1和k2的值是一樣的,但是他們在Map結構中被視爲兩個鍵。即同樣值的兩個實例,在Map中被視爲兩個鍵。

屬性和方法

Map結構有以下屬性和方法:
- size : 返回成員總數。
- set(key, value) : 設置一個鍵值對。
- get(key) : 讀取一個鍵。
- has(key) : 返回一個布爾值,表示某個鍵是否在Map結構中。
- delete(key) : 刪除某個鍵。
- clear() : 清除所有成員。

var m = new Map();

m.set("edition", 6); // 鍵是字符串
m.set(262, "standard"); // 鍵是數字
m.set(undefined, "nah"); //鍵是undefined

var hello = function() {
    console.log("hello");
}
m.set(hello, "Hello ES6!");  //鍵是函數

m.has("edition");  //true
m.has("years");  //false
m.has(262);  //true
m.has(undefined);  //true
m.has(hello);  //true

m.delete( undefined );  
m.has( undefined );  //false

m.get( hello );  //hello ES6!
m.get("edition");  //6

遍歷

Map原生提供三個遍歷器。

  • key() : 返回鍵名的遍歷器。
  • values() : 返回鍵值的遍歷器。
  • entries() : 返回所有成員的遍歷器。
for ( let key of map.key() ) {
    console.log("key: %s", key);
}

for ( let value of map.value() ) {
    console.log("value: %s", value);
}

for ( let item of map.entries() ) {
    console.log("Key: %s, Value: %s", item[0], item[1]);
}

// same as using map.entries()
for (let item of map) {
    console.log("Key: %s, Value: %s", item[0], item[1]);
}

另外,Map還有一個forEach方法,與數組中的forEach方法類似,也可以實現遍歷。

map.forEach(function(value, key, map) {
    console.log("Key: %s, Value: %s", key, value);
});

forEach方法還可接受第二個參數,用來綁定this

var reporter = {
    report: function(key, value) {
        console.log("key: %s, Value: %s", key, value);
    }
};

map.forEach(function(value, key, map) {
    this.report(key, value)
}, reporter);

上面代碼中,forEach()方法的回調函數中的this, 就指向reporter

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