ES6提供了新的數據結構Set,相似數組,元素值都是惟一的,不能重複。Set自己就是一個構造函數。數組
Set接受數組或者類數組做爲參數用來初始化:bash
var arr1 = new Set([1, 2, 5, 1, 2]);
var arr2 = new Set('12512');
console.log(arr1);
console.log(arr2);
複製代碼
var arr = new Set([NaN, NaN]);
console.log(arr);//NaN
console.log(NaN === NaN);//false
複製代碼
Set的屬性和方法:數據結構
Add(value),添加某個值,返回Set結構自己:函數
var arr = new Set();
arr.add(1);
arr.add(2);
console.log(...arr);//1 2
複製代碼
Delete(value),刪除某個值,返回布爾值,表示成功失敗:ui
console.log(arr.delete(1));//truespa
has(value),返回一個布爾值,表示該值是否爲Set的成員。code
console.log(arr.has(2));//trueorm
Clear(),清除全部元素,無返回值:cdn
arr.clear();對象
console.log(arr);//{}
Size,返回元素總數:
console.log(arr.size);//2
Array.form能夠把Set數據結構轉成數組,能夠用來去重:
var arr = [1, 2, 1, 3, 4, 3, 2, 1, 5, 2];
var setArr = new Set(arr);
console.log(Array.from(setArr));//[1, 2, 3, 4, 5]
複製代碼
遍歷keys、values、entries:
Set數據結構沒有鍵名,也能夠說鍵名鍵值是同一個,因此這三個遍歷出來的都同樣,區分的話就是keys是鍵名,values是鍵值,entries是鍵值對:
var arr = new Set(['a', 'b', 'c']);
for(var i of arr.keys()){
console.log(i);//a b c
}
for(var i of arr.values()){
console.log(i);//a b c
}
for(var i of arr.entries()){
console.log(i);//['a', 'a'] ["b", "b"] ["c", "c"]
}
複製代碼
Set結構默承認遍歷,默認遍歷的就是values,能夠用for of直接遍歷:
for(var i of arr){
console.log(i);//a b c
}
複製代碼
Set結構也能夠用forEach遍歷,由於Set結構能夠用擴展運算符,能夠變通的數組去重和使用數組的遍歷方法:
var arr = [1, 2, 1, 3, 4, 3, 2, 1, 5, 2];
console.log([...new Set(arr)]);//[1, 2, 3, 4, 5]
複製代碼
ES6提供了跟Set結構相似的WeakSet,也是不重複的集合,可是WeakSet只能是對象,其餘類型的值都會報錯:
var ws = new WeakSet();
ws.add(1)//TypeError
ws.add('a')//TypeError
ws.add({a: 10})
複製代碼
垃圾回收機制不會回收被全局引用的變量,而WeakSet 中的對象都是弱引用,即垃圾回收機制不考慮 WeakSet 對該對象的引用。
若是其餘對象都再也不引用該對象,那麼垃圾回收機制會自動回收該對象所佔用的內存,不考慮該對象還存在於 WeakSet 之中。
WeakSet 裏面的引用,都不計入垃圾回收機制,所以,WeakSet 適合臨時存放一組對象,以及存放跟對象綁定的信息。只要這些對象在外部消失,它在 WeakSet 裏面的引用就會自動消失。
因爲上面這個特色,WeakSet 的成員是不適合引用的,由於它會隨時消失。另外,因爲 WeakSet 內部有多少個成員,取決於垃圾回收機制有沒有運行,運行先後極可能成員個數是不同的,而垃圾回收機制什麼時候運行是不可預測的,所以 ES6 規定 WeakSet 不可遍歷。
總結一下就是,WeakSet的實例對象就算是全局的,也有能夠被直接回收。
WeskSet有add、delete、has方法沒跟Set同樣,可是隻能是對象或者相似對象的數組,好比:
var ws = new WeakSet();
ws.add([[1, 1], [2, 2]])
WeakSet沒有size屬性,不能遍歷。所以WeakSet的一個做用就是用來存儲DOM節點。其餘還真不知道什麼用。
ES6提供了Map數據結構本質上仍是鍵值對的集合,可是傳統對象只能是字符串作鍵名,好比:
var el = document.getElementById('te');
var obj = {};
obj[el] = 'te';
console.log(obj);//{[object HTMLDivElement]: "te"}
複製代碼
Map數據結構最主要的就是解決這個問題,鍵值還能夠是對象:
var el = document.getElementById('te');
var obj = new Map();
obj.set(el, 'te');
console.log(obj);//{{div#te => "te"}
複製代碼
Map有set、get、delete、clear和has方法和size屬性:
console.log(obj.get(el));//'te'
console.log(obj.has(el));//true
console.log(obj.size);//1
obj.delete(el);
obj.clear();
console.log(obj.has(el));//false
複製代碼
Map接收的數組參數的時候,必定是這樣的:
var obj = new Map([['a', 'a'], ['b', 'b']]);
其餘的操做就跟普通對象操做原理同樣,只有一個須要注意,Map的鍵跟內存地址有關:
var map = new Map();
map.set(['a'], 123);
console.log(map.get(['a']));//undefined
複製代碼
數組的內存地址是不一樣的
map.set(-0, 123);
console.log(map.get(+0)); // 123
map.set(true, 1);
map.set('true', 2);
console.log(map.get(true)); // 1
console.log(map.get('true')); // 2
map.set(undefined, 3);
map.set(null, 4);
console.log(map.get(undefined)); // 3
map.set(NaN, 123);
console.log(map.get(NaN)); // 123
複製代碼
Map和Set同樣,也有keys、values、entries和forEach遍歷方法,且順序就是插入順序,使用for of方法,一樣的,使用擴展運算符也能很快的轉爲數組,轉成數組以後也就間接的能使用數組的map、filter等數組方法。這邊就不上代碼了,跟Set同樣。
Map數據結構,能夠直接或者間接的準成數組或者JSON或者對象,相應的,數組或者JSON或者對象也能轉成Map數據結構。
ES6提供了跟Map相似的WeakMap數據結構,二者都差很少,區別有兩點,第一就是WeakMap的鍵必定要對象,不然報錯,另一點跟WeakSet同樣,不計入垃圾回收機制。
它的鍵名所引用的對象都是弱引用,即垃圾回收機制不將該引用考慮在內。所以,只要所引用的對象的其餘引用都被清除,垃圾回收機制就會釋放該對象所佔用的內存。也就是說,一旦再也不須要,WeakMap 裏面的鍵名對象和所對應的鍵值對會自動消失,不用手動刪除引用。
要注意的是,是鍵名是弱引用,鍵值依然可使用:
var map = new WeakMap();
var key = {};
var val = 'map';
map.set(key, val);
val = null;
console.log(map.get(key));//map
複製代碼
也就是說val即便是消除了,WeakMap內部依然能使用。
由於WeakMap和Map的區別,鍵名是否存在不可預測,跟垃圾回收機制是否運行有關,因此WeakMap其餘方法都沒有隻有get、set、has、delete方法。
WeakMap典型場合也是DOM節點做爲鍵名,一旦DOM節點刪除了,WeakMap裏面的也會隨之消失,不會形成內存泄漏風險:
var map = new WeakMap();
var key = document.getElementById('te');
var val = 1;
map.set(key, val);
key.addEventListener('click', function() {
let val = myWeakmap.get(myElement);
val++;
}, false);
複製代碼
一旦DOM節點消失,那麼該val也會消失。
Coding 我的筆記