ES6中Set和Map用法實(shí)例詳解
本文實(shí)例講述了ES6中Set和Map用法。分享給大家供大家參考,具體如下:
Set
ES6提供了新的數(shù)據(jù)結(jié)構(gòu)Set。它類似于數(shù)組,但是成員的值都是唯一的,沒有重復(fù)的值。
Set函數(shù)可以接受一個(gè)數(shù)組(或類似數(shù)組的對象)作為參數(shù),用來初始化。
// 例一
var set = new Set([1, 2, 3, 4, 4]);
[...set]
// [1, 2, 3, 4]
var s = new Set();
[2, 3, 5, 4, 5, 2, 2].map(x => s.add(x));
for (let i of s) {
console.log(i);
}
// 2 3 5 4
注:在Set內(nèi)部,兩個(gè)NaN是相等。兩個(gè)對象總是不相等的。可以用length來檢測
let set = new Set();
let a = NaN;
let b = NaN;
set.add(a);
set.add(b);
set // Set {NaN}
let set = new Set();
set.add({});
set.size // 1
set.add({});
set.size // 2
var arr=[
{id:1,name:'葉落森'},
{id:2,name:'葉落森'},
{id:3,name:'葉落森'},
{id:4,name:'葉落森'},
{id:2,name:'葉落森'}
]
const s = new Set();
arr.forEach(x => s.add(x));
for (let i of s) {
console.log(i);
}
四個(gè)操作方法:
add(value):添加某個(gè)值,返回Set結(jié)構(gòu)本身。delete(value):刪除某個(gè)值,返回一個(gè)布爾值,表示刪除是否成功。has(value):返回一個(gè)布爾值,表示該值是否為Set的成員。clear():清除所有成員,沒有返回值
let s = new Set(); s.add(1).add(2).add(2); // 注意2被加入了兩次 s.size // 2 s.has(1) // true s.has(2) // true s.has(3) // false console.log(s.delete(2));//true s.has(2) // false
set內(nèi)部的元素可以遍歷for...of...
遍歷操作
Set 結(jié)構(gòu)的實(shí)例有四個(gè)遍歷方法,可以用于遍歷成員。
keys():返回鍵名的遍歷器values():返回鍵值的遍歷器entries():返回鍵值對的遍歷器forEach():使用回調(diào)函數(shù)遍歷每個(gè)成員
需要特別指出的是,Set的遍歷順序就是插入順序。這個(gè)特性有時(shí)非常有用,比如使用 Set 保存一個(gè)回調(diào)函數(shù)列表,調(diào)用時(shí)就能保證按照添加順序調(diào)用。
(1)keys(),values(),entries()
keys方法、values方法、entries方法返回的都是遍歷器對象。由于 Set 結(jié)構(gòu)沒有鍵名,只有鍵值(或者說鍵名和鍵值是同一個(gè)值),所以keys方法和values方法的行為完全一致。
let set = new Set(['red', 'green', 'blue']);
for (let item of set.keys()) {
console.log(item);
}
// red
// green
// blue
for (let item of set.values()) {
console.log(item);
}
// red
// green
// blue
for (let item of set.entries()) {
console.log(item);
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]
Set 結(jié)構(gòu)的實(shí)例默認(rèn)可遍歷,它的默認(rèn)遍歷器生成函數(shù)就是它的values方法。
這意味著,可以省略values方法,直接用for...of循環(huán)遍歷 Set。
let set = new Set(['red', 'green', 'blue']);
for (let x of set) {
console.log(x);
}
// red
// green
// blue
Set 結(jié)構(gòu)的實(shí)例與數(shù)組一樣,也擁有forEach方法,用于對每個(gè)成員執(zhí)行某種操作,沒有返回值
set = new Set([1, 4, 9]); set.forEach((value, key) => console.log(key + ' : ' + value)) // 1 : 1 // 4 : 4 // 9 : 9
Map
Map結(jié)構(gòu)提供了“值—值”的對應(yīng),是一種更完善的Hash結(jié)構(gòu)實(shí)現(xiàn)。如果你需要“鍵值對”的數(shù)據(jù)結(jié)構(gòu),Map比Object更合適。它類似于對象,也是鍵值對的集合,但是“鍵”的范圍不限于字符串,各種類型的值(包括對象)都可以當(dāng)作鍵。
var m = new Map();
var o = {p: "Hello World"};
m.set(o, "content")
m.get(o) // "content"
m.has(o) // true
m.delete(o) // true
m.has(o) // false
注意,只有對同一個(gè)對象的引用,Map結(jié)構(gòu)才將其視為同一個(gè)鍵。這一點(diǎn)要非常小心。
var map = new Map(); map.set(['a'], 555); map.get(['a']) // undefined
上面代碼的set和get方法,表面是針對同一個(gè)鍵,但實(shí)際上這是兩個(gè)值,內(nèi)存地址是不一樣的,因此get方法無法讀取該鍵,返回undefined。
注:如果Map的鍵是一個(gè)簡單類型的值(數(shù)字、字符串、布爾值),則只要兩個(gè)值嚴(yán)格相等,Map將其視為一個(gè)鍵,包括0和-0。另外,雖然NaN不嚴(yán)格相等于自身,但Map將其視為同一個(gè)鍵。
實(shí)例屬性和方法:size、set、get、has、delete、clear
遍歷方法:keys()、values()、entries()、forEach()
const map = new Map([
['F', 'no'],
['T', 'yes'],
]);
for (let key of map.keys()) {
console.log(key);
}
// "F"
// "T"
for (let value of map.values()) {
console.log(value);
}
// "no"
// "yes"
for (let item of map.entries()) {
console.log(item[0], item[1]);
}
// "F" "no"
// "T" "yes"
// 或者
for (let [key, value] of map.entries()) {
console.log(key, value);
}
// "F" "no"
// "T" "yes"
// 等同于使用map.entries()
for (let [key, value] of map) {
console.log(key, value);
}
// "F" "no"
// "T" "yes"
Map 結(jié)構(gòu)轉(zhuǎn)為數(shù)組結(jié)構(gòu),比較快速的方法是使用擴(kuò)展運(yùn)算符(...)。
const map = new Map([ [1, 'one'], [2, 'two'], [3, 'three'], ]); [...map.keys()] // [1, 2, 3] [...map.values()] // ['one', 'two', 'three'] [...map.entries()] // [[1,'one'], [2, 'two'], [3, 'three']] [...map] // [[1,'one'], [2, 'two'], [3, 'three']]
結(jié)合數(shù)組的map方法、filter方法,可以實(shí)現(xiàn) Map 的遍歷和過濾(Map 本身沒有map和filter方法)。
const map0 = new Map()
.set(1, 'a')
.set(2, 'b')
.set(3, 'c');
const map1 = new Map(
[...map0].filter(([k, v]) => k < 3)
);
// 產(chǎn)生 Map 結(jié)構(gòu) {1 => 'a', 2 => 'b'}
const map2 = new Map(
[...map0].map(([k, v]) => [k * 2, '_' + v])
);
// 產(chǎn)生 Map 結(jié)構(gòu) {2 => '_a', 4 => '_b', 6 => '_c'}
此外,Map 還有一個(gè)forEach方法,與數(shù)組的forEach方法類似,也可以實(shí)現(xiàn)遍歷。
map.forEach(function(value, key, map) {
console.log("Key: %s, Value: %s", key, value);
});
區(qū)別:
set是一種關(guān)聯(lián)式容器,其特性如下:
- set以RBTree作為底層容器
- 所得元素的只有key沒有value,value就是key
- 不允許出現(xiàn)鍵值重復(fù)
- 所有的元素都會(huì)被自動(dòng)排序
- 不能通過迭代器來改變set的值,因?yàn)閟et的值就是鍵
map和set一樣是關(guān)聯(lián)式容器,它們的底層容器都是紅黑樹,區(qū)別就在于map的值不作為鍵,鍵和值是分開的。它的特性如下:
- map以RBTree作為底層容器
- 所有元素都是鍵+值存在
- 不允許鍵重復(fù)
- 所有元素是通過鍵進(jìn)行自動(dòng)排序的
- map的鍵是不能修改的,但是其鍵對應(yīng)的值是可以修改的
weakset
WeakSet結(jié)構(gòu)與Set類似,也是不重復(fù)的值的集合。
WeakSet和Set的區(qū)別:
- WeakSet的成員只能是對象,而不能是其他類型的值
- WeakSet中的對象都是弱引用,即垃圾回收機(jī)制不考慮WeakSet對該對象的引用,也就是說,如果其他對象都不再引用該對象,那么垃圾回收機(jī)制會(huì)自動(dòng)回收該對象所占用的內(nèi)存,不考慮該對象還存在于WeakSet之中。這個(gè)特點(diǎn)意味著,無法引用WeakSet的成員,因此WeakSet是不可遍歷的。
WeakMap可以參考WeakSet
感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運(yùn)行工具:http://tools.jb51.net/code/HtmlJsRun測試上述代碼運(yùn)行效果。
更多關(guān)于JavaScript相關(guān)內(nèi)容可查看本站專題:《JavaScript操作DOM技巧總結(jié)》、《JavaScript頁面元素操作技巧總結(jié)》、《JavaScript事件相關(guān)操作與技巧大全》、《JavaScript查找算法技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》
希望本文所述對大家JavaScript程序設(shè)計(jì)有所幫助。
相關(guān)文章
uniapp中使用vuex的過程(解決uniapp無法在data和template中獲取vuex數(shù)據(jù)問題)
這篇文章主要介紹了uniapp中使用vuex(解決uniapp無法在data和template中獲取vuex數(shù)據(jù)問題),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-05-05
javascript性能優(yōu)化之DOM交互操作實(shí)例分析
這篇文章主要介紹了javascript性能優(yōu)化之DOM交互操作技巧,結(jié)合實(shí)例形式總結(jié)分析了JavaScript針對DOM操作過程中的各種常見優(yōu)化操作技巧,需要的朋友可以參考下2015-12-12
js判斷iframe中元素是否存在的實(shí)現(xiàn)代碼
這篇文章主要介紹了js判斷iframe中元素是否存在的實(shí)現(xiàn)代碼,需要的朋友可以參考下2016-12-12
IE與Firefox在JavaScript上的7個(gè)不同句法分享
盡管那需要用長串的、沉悶的不同分支代碼來應(yīng)付不同瀏覽器的日子已經(jīng)過去,偶爾還是有必要做一些簡單的區(qū)分和目標(biāo)檢測來確保某塊代碼能在用戶的機(jī)器上正常運(yùn)行2011-10-10
如何用JavaScript實(shí)現(xiàn)功能齊全的單鏈表詳解
這篇文章主要給大家介紹了關(guān)于如何用JavaScript實(shí)現(xiàn)功能齊全的單鏈表的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02
JS實(shí)現(xiàn)排行榜文字向上滾動(dòng)輪播效果
這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)排行榜文字向上滾動(dòng)輪播效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
momentjs實(shí)現(xiàn)DatePicker時(shí)間禁用的項(xiàng)目實(shí)踐
momentjs是一個(gè)處理時(shí)間的js庫,簡潔易用,本文來介紹一下momentjs實(shí)現(xiàn)DatePicker時(shí)間禁用,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09
用showModalDialog彈出頁面后,提交表單總是彈出一個(gè)新窗口
用showModalDialog彈出頁面后,提交表單總是彈出一個(gè)新窗口,其實(shí)解決方法很簡單如下。2009-07-07

