Set和Map資料結構
阿新 • • 發佈:2019-01-04
1.Set
基本用法
Set是一個建構函式,用來生成Set資料結構,它類似於陣列,但是成員的值都是唯一的,沒有重複的值,接收一個數組(或類似陣列的物件)作為引數,用來初始化。const s =newSet();
[2,3,5,4,5,2,2].forEach(x => s.add(x));
for(let i of s){
console.log(i);
}
// 2 3 5 4
// 用途:去除陣列的重複成員
[...newSet(array)]
- 向Set加入值時,不會發生型別轉換,5和"5"是兩個不同的值。
- 在Set內部,兩個NaN是相等的。
- 兩個物件總是不相等的。
Set例項的屬性和方法
屬性
- Set.prototype.constructor:建構函式,預設就是Set函式
- Set.prototype.size:返回Set例項的成員總數
方法
操作方法(操作資料):- add(value):新增某個值,返回Set結構本身
- delete(value):刪除某個值,返回一個布林值,表示刪除是否成功
- has(value):返回一個布林值,表示該值是否為Set的成員
- clear(value):清除所有成員,沒有返回值
function dedupe(array){
returnArray.from(
}
dedupe([1,1,2,3])// [1, 2, 3]
- keys():返回鍵名的遍歷器
- values():返回鍵值的遍歷器,Set結構沒有鍵名,鍵名和鍵值是同一個值
- entries():返回鍵值對的遍歷器
- forEach():使用回撥函式遍歷每個成員,用於對每個成員執行某種操作,沒有返回值,引數依次為鍵值、鍵名、集合本身,還可以有第二個引數,表示繫結的this物件
for(let item of set.values()){//可以寫成let item of set,因為預設遍歷器生成函式就是values方法
console.log(
}
// red
// green
// blue
for(let item of set.entries()){
console.log(item);
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]
let set = new Set([1, 2, 3]);
set.forEach((value, key) => console.log(value * 2) )
// 2
// 4
// 6
2.WeakSet
含義
與Set類似,也是不重複的值的集合,但是它的成員只能是物件,不能是其他型別的值,其中的物件都是弱引用,如果其他物件都不再引用該物件,那麼垃圾回收機制會主動回收該物件所佔的記憶體,不考慮該物件還存在於WeakSet之中,WeakSet適合臨時存放一組物件,以及存放跟物件繫結的資訊。- WeakSet不能遍歷,因為成員都是弱引用,隨時可能消失。
- WeakSet有三個方法:add、delete、has
- WeakSet沒有size屬性,不能遍歷成員
const a =[[1,2],[3,4]];
const ws =newWeakSet(a);
// WeakSet {[1, 2], [3, 4]}
3.Map
含義和基本用法
Map資料結構類似於物件,也是鍵值對的集合,但是鍵的範圍不限於字串,各種型別的值都可以當做鍵,是一種更完善的Hash結構實現,作為建構函式,Map也可以接受一個數組作為引數,陣列成員是一個個表示鍵值對的陣列。const map =newMap([
['name','張三'],
['title','Author']
]);
map.size // 2
map.has('name')// true
map.get('name')// "張三"
map.has('title')// true
map.get('title')// "Author"
- 如果對同一個鍵多次賦值,後面的值將覆蓋前面的值。
- 如果讀取一個未知的鍵,返回undefined。
- 只有對同一個物件的引用,Map結構才視為同一個鍵,set和get方法表面是針對同一個值,實際上是兩個值,記憶體地址是不一樣的。
- 同一個值的兩個例項,在Map結構中被視為兩個鍵。
- 如果Map的鍵是一個簡單型別的值(數字、字串、布林值),0和-0是同一個鍵,布林值true和字串true是兩個不同的鍵,NaN是同一個鍵。
let map =newMap();
map.set(-0,123);
map.get(+0)// 123
例項的屬性和操作方法
size屬性:返回Map結構的成員總數 set(key,value)方法:設定/更新鍵名key對應的鍵值為value,然後返回整個Map結構,可以採用鏈式寫法 get(key):讀取key對應的鍵值,找不到返回undefined has(key):返回布林值,表示某個鍵是否在當前Map中 delete(key):返回布林值,表示是否刪除成功 clear():清除所有成員,沒有返回值 遍歷方法和Set相同,keys()、values()、entries()、forEach()與其他資料結構的相互轉換
- Map轉為陣列:使用擴充套件運算子
const myMap =newMap()
.set(true,7)
.set({foo:3},['abc']);
[...myMap]
// [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]
- 陣列轉為Map:將陣列傳入Map建構函式
newMap([
[true,7],
[{foo:3},['abc']]
])
// Map {
// true => 7,
// Object {foo: 3} => ['abc']
// }
- Map轉為物件:所有Map的鍵都是字串,則可以轉為物件,使用Object.create建立物件,然後迴圈賦值
function strMapToObj(strMap){
let obj =Object.create(null);
for(let [k,v] of strMap){
obj[k]= v;
}
return obj;
}
const myMap =newMap()
.set('yes',true)
.set('no',false);
strMapToObj(myMap)
// { yes: true, no: false }
- 物件轉為Map:遍歷物件,使用Map的set方法
function objToStrMap(obj){
let strMap =newMap();
for(let k of Object.keys(obj)){
strMap.set(k, obj[k]);
}
return strMap;
}
objToStrMap({yes:true, no:false})
// Map {"yes" => true, "no" => false}
- Map轉為JSON:Map的鍵名如果是字串,則轉為物件JSON,如果含有非字串,則轉為陣列JSON
//物件JSON
function strMapToJson(strMap){
return JSON.stringify(strMapToObj(strMap));
}
let myMap =newMap().set('yes',true).set('no',false);
strMapToJson(myMap)
// '{"yes":true,"no":false}'
陣列 JSON
function mapToArrayJson(map){
return JSON.stringify([...map]);
}
let myMap =newMap().set(true,7).set({foo:3},['abc']);
mapToArrayJson(myMap)
// '[[true,7],[{"foo":3},["abc"]]]'
- JSON轉為Map
function jsonToStrMap(jsonStr){
return objToStrMap(JSON.parse(jsonStr));
}
jsonToStrMap('{"yes": true, "no": false}')
// Map {'yes' => true, 'no' => false}
4.WeakMap
含義
與Map結構類似,也是用於生成鍵值對的集合,只接受物件作為鍵名(null除外),不接受其他型別的值作為鍵名,WeakMap的鍵名所指向的物件,不計入垃圾回收機制,它沒有遍歷操作,無法清空。應用
註冊監聽事件的listener物件,監聽函式放在WeakMap裡面,一旦DOM物件消失,和它繫結的監聽函式也會消失const listener =newWeakMap();
listener.set(element1, handler1);
listener.set(element2, handler2);
element1.addEventListener('click', listener.get(element1),false