本文是 重溫基礎 系列文章的第十一篇。
今日感受:注意身體,生病花錢又難受。
系列目錄:
- 【複習資料】ES6/ES7/ES8/ES9資料整理(個人整理)
- 【重溫基礎】1.語法和資料型別
- 【重溫基礎】2.流程控制和錯誤處理
- 【重溫基礎】3.迴圈和迭代
- 【重溫基礎】4.函式
- 【重溫基礎】5.表示式和運算子
- 【重溫基礎】6.數字
- 【重溫基礎】7.時間物件
- 【重溫基礎】8.字串
- 【重溫基礎】9.正規表示式
- 【重溫基礎】10.陣列
本章節複習的是JS中的Map和Set物件,是個集合。
前置知識:
Map和Set物件是在ES6中被引入的,作為一種由key
值標記的資料容器。
Map和Set物件承載的資料元素可以按照插入時的順序,被迭代遍歷。
1 Set物件
介紹: Set
資料結構類似陣列,但所有成員的值唯一。 Set
本身為一個建構函式,用來生成Set
資料結構,使用add
方法來新增新成員。
let a = new Set();
[1,2,2,1,3,4,5,4,5].forEach(x=>a.add(x));
for(let k of a){
console.log(k)
};
// 1 2 3 4 5
基礎使用:
let a = new Set([1,2,3,3,4]);
[...a]; // [1,2,3,4]
a.size; // 4
// 陣列去重
[...new Set([1,2,3,4,4,4])];// [1,2,3,4]
注意:
- 向
Set
中新增值的時候,不會型別轉換,即5
和`5`
是不同的。
[...new Set([5,`5`])]; // [5, "5"]
屬性和方法:
-
屬性:
-
Set.prototype.constructor
:建構函式,預設就是Set
函式。 -
Set.prototype.size
:返回Set
例項的成員總數。
-
-
操作方法:
-
add(value)
:新增某個值,返回 Set 結構本身。 -
delete(value)
:刪除某個值,返回一個布林值,表示刪除是否成功。 -
has(value)
:返回一個布林值,表示該值是否為Set的成員。 -
clear()
:清除所有成員,沒有返回值。
-
let a = new Set();
a.add(1).add(2); // a => Set(2) {1, 2}
a.has(2); // true
a.has(3); // false
a.delete(2); // true a => Set(1) {1}
a.clear(); // a => Set(0) {}
陣列去重:
let a = new Set([1,2,3,3,3,3]);
2 Set的應用
陣列去重:
// 方法1
[...new Set([1,2,3,4,4,4])]; // [1,2,3,4]
// 方法2
Array.from(new Set([1,2,3,4,4,4])); // [1,2,3,4]
遍歷和過濾:
let a = new Set([1,2,3,4]);
// map 遍歷操作
let b = new Set([...a].map(x =>x*2));// b => Set(4) {2,4,6,8}
// filter 過濾操作
let c = new Set([...a].filter(x =>(x%2) == 0)); // b => Set(2) {2,4}
獲取並集、交集和差集:
let a = new Set([1,2,3]);
let b = new Set([4,3,2]);
// 並集
let c1 = new Set([...a, ...b]); // Set {1,2,3,4}
// 交集
let c2 = new Set([...a].filter(x => b.has(x))); // set {2,3}
// 差集
let c3 = new Set([...a].filter(x => !b.has(x))); // set {1}
-
遍歷方法:
-
keys()
:返回鍵名的遍歷器。 -
values()
:返回鍵值的遍歷器。 -
entries()
:返回鍵值對的遍歷器。 -
forEach()
:使用回撥函式遍歷每個成員。
-
Set
遍歷順序是插入順序,當儲存多個回撥函式,只需按照順序呼叫。但由於Set
結構沒有鍵名只有鍵值,所以keys()
和values()
是返回結果相同。
let a = new Set([`a`,`b`,`c`]);
for(let i of a.keys()){console.log(i)}; // `a` `b` `c`
for(let i of a.values()){console.log(i)}; // `a` `b` `c`
for(let i of a.entries()){console.log(i)};
// [`a`,`a`] [`b`,`b`] [`c`,`c`]
並且 還可以使用for...of
直接遍歷Set
。
let a = new Set([`a`,`b`,`c`]);
for(let k of a){console.log(k)}; // `a` `b` `c`
forEach
與陣列相同,對每個成員執行操作,且無返回值。
let a = new Set([`a`,`b`,`c`]);
a.forEach((v,k) => console.log(k + ` : ` + v));
3 Map物件
由於傳統的JavaScript
物件只能用字串當做鍵,給開發帶來很大限制,ES6增加Map
資料結構,使得各種型別的值(包括物件)都可以作為鍵。 Map
結構提供了“值—值”的對應,是一種更完善的 Hash 結構實現。
基礎使用:
let a = new Map();
let b = {name: `leo` };
a.set(b,`my name`); // 新增值
a.get(b); // 獲取值
a.size; // 獲取總數
a.has(b); // 查詢是否存在
a.delete(b); // 刪除一個值
a.clear(); // 清空所有成員 無返回
注意:
- 傳入陣列作為引數,指定鍵值對的陣列。
let a = new Map([
[`name`,`leo`],
[`age`,18]
])
- 如果對同一個鍵多次賦值,後面的值將覆蓋前面的值。
let a = new Map();
a.set(1,`aaa`).set(1,`bbb`);
a.get(1); // `bbb`
- 如果讀取一個未知的鍵,則返回
undefined
。
new Map().get(`abcdef`); // undefined
- 同樣的值的兩個例項,在 Map 結構中被視為兩個鍵。
let a = new Map();
let a1 = [`aaa`];
let a2 = [`aaa`];
a.set(a1,111).set(a2,222);
a.get(a1); // 111
a.get(a2); // 222
遍歷方法:
Map 的遍歷順序就是插入順序。
-
keys()
:返回鍵名的遍歷器。 -
values()
:返回鍵值的遍歷器。 -
entries()
:返回所有成員的遍歷器。 -
forEach()
:遍歷 Map 的所有成員。
let a = new Map([
[`name`,`leo`],
[`age`,18]
])
for (let i of a.keys()){...};
for (let i of a.values()){...};
for (let i of a.entries()){...};
a.forEach((v,k,m)=>{
console.log(`key:${k},value:${v},map:${m}`)
})
將Map結構轉成陣列結構:
let a = new Map([
[`name`,`leo`],
[`age`,18]
])
let a1 = [...a.keys()]; // a1 => ["name", "age"]
let a2 = [...a.values()]; // a2 => ["leo", 18]
let a3 = [...a.entries()];// a3 => [[`name`,`leo`], [`age`,18]]
4 Map與其他資料結構互相轉換
- Map 轉 陣列
let a = new Map().set(true,1).set({f:2},[`abc`]);
[...a]; // [[true:1], [ {f:2},[`abc`] ]]
- 陣列 轉 Map
let a = [ [`name`,`leo`], [1, `hi` ]]
let b = new Map(a);
- Map 轉 物件
如果所有 Map 的鍵都是字串,它可以無損地轉為物件。
如果有非字串的鍵名,那麼這個鍵名會被轉成字串,再作為物件的鍵名。
function fun(s) {
let obj = Object.create(null);
for (let [k,v] of s) {
obj[k] = v;
}
return obj;
}
const a = new Map().set(`yes`, true).set(`no`, false);
fun(a)
// { yes: true, no: false }
- 物件 轉 Map
function fun(obj) {
let a = new Map();
for (let k of Object.keys(obj)) {
a.set(k, obj[k]);
}
return a;
}
fun({yes: true, no: false})
// Map {"yes" => true, "no" => false}
- Map 轉 JSON
(1)Map鍵名都是字串,轉為物件JSON:
function fun (s) {
let obj = Object.create(null);
for (let [k,v] of s) {
obj[k] = v;
}
return JSON.stringify(obj)
}
let a = new Map().set(`yes`, true).set(`no`, false);
fun(a);
// `{"yes":true,"no":false}`
(2)Map鍵名有非字串,轉為陣列JSON:
function fun (map) {
return JSON.stringify([...map]);
}
let a = new Map().set(true, 7).set({foo: 3}, [`abc`]);
fun(a)
// `[[true,7],[{"foo":3},["abc"]]]`
- JSON 轉 Map
(1)所有鍵名都是字串:
function fun (s) {
let strMap = new Map();
for (let k of Object.keys(s)) {
strMap.set(k, s[k]);
}
return strMap;
return JSON.parse(strMap);
}
fun(`{"yes": true, "no": false}`)
// Map {`yes` => true, `no` => false}
(2)整個 JSON 就是一個陣列,且每個陣列成員本身,又是一個有兩個成員的陣列:
function fun2(s) {
return new Map(JSON.parse(s));
}
fun2(`[[true,7],[{"foo":3},["abc"]]]`)
// Map {true => 7, Object {foo: 3} => [`abc`]}
參考資料
本部分內容到這結束
Author | 王平安 |
---|---|
pingan8787@qq.com | |
博 客 | www.pingan8787.com |
微 信 | pingan8787 |
每日文章推薦 | https://github.com/pingan8787… |
JS小冊 | js.pingan8787.com |
歡迎關注微信公眾號【前端自習課】每天早晨,與您一起學習一篇優秀的前端技術博文 .