ES6新增 Map
Map
(1)基本語法
javascript的物件(Object)本質上是鍵值對的集合,只能用字串作為鍵名,對於其他的型別,會自動轉為字串:
let array_ = [1, 2, 3, 4];//陣列
let function_ = function () {};//函式
let number_=123;//數字
let object_={};//物件
let a = {};
a[number_]="q";
a[array_]="qe";
a[function_]="qwe";
a[object_]="qwer" ;
let p = Object.keys(a);
console.log(p);//["123","1,2,3,4","function(){}","[object object]"]
console.log(typeof p[0]);//string
console.log(typeof p[1]);//string
console.log(typeof p[2]);//string
console.log(typeof p[3]);//string
為了解決這個問題ES6提供了Map資料結構,它類似物件,也是鍵值對的集合,但是鍵名可以是各種型別:
let number_=123;//數字
let array_ = [1, 2, 3, 4];//陣列
let function_ = function () {};//函式
let object_={};//物件
const a=new Map();
a.set(number_,"q");
a.set(array_,"qw");
a.set(function_ ,"qwe");
a.set(object_,"qwer");
a.get(number_);//q
a.get(array_);//qw
a.get(function_) ;//qwe
a.get(object_);//qwer
for(let key of a.keys()){
console.log(typeof key);
}
//number
//object
//function
//object
上面用到了Map結構的get和set操作方法。
Map建構函式
任何具有Iterator介面,且每個成員都是一個雙元素陣列的資料結構都可以當作Map建構函式的引數。例如陣列:
const map = new Map([
[1,"one"],
[2, "two"],
[3, "three"]
]);
// Map{
// 1 => "one",
// 2 => "two",
// 3 => "three"
// }
如果傳入的陣列成員是存在三個元素的陣列,則會忽略第三個元素:
const map = new Map([
[1,"one","_one"],
[2, "two"],
[3, "three"]
]);
// Map{
// 1 => "one",
// 2 => "two",
// 3 => "three"
// }
陣列的成員存在單元素陣列:
const map = new Map([
[1],
[2, "two"],
[3, "three"]
]);
// Map{
// 1 => undefined,
// 2 => "two",
// 3 => "three"
// }
除了陣列,Map和Set都可以用來生成新的Map。
Map的鍵與記憶體地址繫結
const map=new Map();
//雖然k1和k2的值是相同的,但k1和k2儲存的記憶體地址是不同的
const k1=["a"];
const k2=["a"];
map.set(k1,111)
.set(k2,111);
map.get(k1);// 111
map.get(k2);// 222
Map的鍵與記憶體地址繫結,只要兩個值的記憶體地址不同,Map就將它們視為兩個鍵。
(2)例項屬性和操作方法
1.size屬性
size屬性返回Map結構的成員總數
let a=new Map();
a.set("1","q");
a.set("2","qw");
console.log(a.size)//2
2.set(key,value)
set方法設定鍵名(key)對應的鍵值(value),返回Map結構。如果設定的key已經有值,則鍵值會被更新。由於set方法返回的是當前的Map物件,因此可以採用鏈式寫法:
let a=new Map();
a.set("1","q")
.set("2","qw")
.set("3","qwe");
3.get(key)
get方法讀取key所對應的鍵值,如果找不到key,返回undefined。
4.has(key)
has方法返回一個布林值,表示某個鍵是否存在Map中。
5.delete(key)
delete方法刪除某個鍵,返回true。如果刪除失敗,返回false。
6.clear()
clear方法清除所有成員,沒有返回值。
(3)遍歷方法
Map的遍歷順序就是插入順序。
1.keys():返回鍵名的遍歷器。
2.values():返回鍵值的遍歷器。
3.entries():返回所有成員的遍歷器。
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結構的預設遍歷器屬性介面(Symbol.iterator屬性)就是entries方法(在Set結構中預設遍歷器生成函式是它的values方法)。
Map結構轉為陣列
Map結構轉為陣列結構的比較快速的方法是結合擴充套件運算子(…)。
const map = new Map([
["1", "one"],
["2", "two"],
["3", "three"]
]);
console.log([...map.keys()]);
//["1","2","3"]
console.log([...map.values()]);
//["one","two","three"]
console.log([...map.entries()]);
//[["1","one"],["2","two"],["3","three"]]
console.log([...map]);
//[["1","one"],["2","two"],["3","three"]]
Map的遍歷和過濾
Map本身沒有map和filter方法,但是可以結合陣列的map方法、filter方法,可以實現Map的遍歷和過濾。
const map = new Map([
[1, "one"],
[2, "two"],
[3, "three"]
]);
const map1=new Map(
[...map].filter(([k,v])=>k<3)
);
//產生map結構 {1=>"one",2=>"b"}
const map2=new Map(
[...map].map(([k,v])=>[k*2,"_"+v])
);
//產生map結構 {2=>"_one",4=>"_two",6=>"_three"}
4.forEach():遍歷Map的所有成員。
Map的forEach方法與陣列的forEach方法類似,可以實現遍歷。
const map = new Map([
[1, "one"],
[2, "two"],
[3, "three"]
]);
map.forEach(function (value, key, map) {
console.log("Key:%s,Value:%s", key, value);
});
// Key:1,Value:one
// Key:2,Value:two
// Key:3,Value:three
forEach方法還可以接受第二個引數,用於繫結this。
const map = new Map([
[1, "one"],
[2, "two"],
[3, "three"]
]);
const reporter={
report:function(key,value){
console.log("Key:%s,Value:%s", key, value);
}
};
map.forEach(function (value, key, map) {
this.report(key,value);
},reporter);
// Key:1,Value:one
// Key:2,Value:two
// Key:3,Value:three
(4)與其他資料結構的轉化
1.Map轉為陣列
Map轉為陣列最方便的方法就是使用擴充套件運算子(…)(這裡的例子和前面的例子相同)
const map = new Map([
["1", "one"],
["2", "two"],
["3", "three"]
]);
console.log([...map.keys()]);
//["1","2","3"]
console.log([...map.values()]);
//["one","two","three"]
console.log([...map.entries()]);
//[["1","one"],["2","two"],["3","three"]]
console.log([...map]);
//[["1","one"],["2","two"],["3","three"]]
2.陣列轉為Map
將陣列傳入建構函式就可以轉為Map。
陣列的成員都是雙元素陣列:
const map = new Map([
[1,"one"],
[2, "two"],
[3, "three"]
]);
// Map{
// 1 => "one",
// 2 => "two",
// 3 => "three"
// }
陣列的成員存在單元素陣列:
const map = new Map([
[1],
[2, "two"],
[3, "three"]
]);
// Map{
// 1 => undefined,
// 2 => "two",
// 3 => "three"
// }
陣列的成員存在三個元素的陣列:
const map = new Map([
[1,"one","_one"],
[2, "two"],
[3, "three"]
]);
// Map{
// 1 => "one",
// 2 => "two",
// 3 => "three"
// }
3.Map轉為物件
如果Map的所有鍵都是字串,則可以轉為物件。
function strMapToObj(strMap) {
let obj = Object.create(null);
for (let [k, v] of strMap) {
obj[k] = v;
}
return obj;
}
const myMap = new Map()
.set('yes', true)
.set('no', false)
let a = strMapToObj(myMap);
console.log(a)
// { yes: true, no: false }
4.物件轉為Map
function objToStrMap(obj) {
let strMap = new Map();
for (let k of Object.keys(obj)) {
strMap.set(k, obj[k]);
}
return strMap;
}
let a=objToStrMap({yes: true, no: false});
console.log(a)
// Map {"yes" => true, "no" => false}
5.Map轉為JSON
Map的鍵名都是字串:
將Map轉為物件,之後呼叫JSON.stringify()轉化為物件JSON:
function strMapToJson(strMap) {
return JSON.stringify(strMapToObj(strMap));
}
let myMap = new Map().set('yes', true).set('no', false);
strMapToJson(myMap)
// '{"yes":true,"no":false}'
Map的鍵名存在非字串:
將Map轉為陣列,之後呼叫JSON.stringify()轉化為陣列JSON:
function mapToArrayJson(map) {
return JSON.stringify([...map]);
}
let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
mapToArrayJson(myMap)
// '[[true,7],[{"foo":3},["abc"]]]'
6.JSON轉為Map
物件JSON(所有鍵名都是字串)轉為Map:
呼叫JSON.parse()將物件JSON(所有鍵名都是字串)轉為物件,之後將物件轉為Map。
function jsonToStrMap(jsonStr) {
return objToStrMap(JSON.parse(jsonStr));
}
jsonToStrMap('{"yes": true, "no": false}')
// Map {'yes' => true, 'no' => false}
陣列JSON(每個陣列成員本身是一個具有兩個成員的陣列)轉為Map:
呼叫JSON.parse()將陣列JSON轉為陣列,之後將陣列傳入Map的建構函式。
function jsonToMap(jsonStr) {
return new Map(JSON.parse(jsonStr));
}
jsonToMap('[[true,7],[{"foo":3},["abc"]]]')
// Map {true => 7, Object {foo: 3} => ['abc']}
陣列成員存在三個元素的陣列,則忽略第三個元素:
function jsonToMap(jsonStr) {
return new Map(JSON.parse(jsonStr));
}
jsonToMap('[[true,7,8],[{"foo":3},["abc"]]]')
// Map {true => 7, Object {foo: 3} => ['abc']}
陣列成員存在單元素的陣列:
function jsonToMap(jsonStr) {
return new Map(JSON.parse(jsonStr));
}
jsonToMap('[[true],[{"foo":3},["abc"]]]')
// Map {true => undefined, Object {foo: 3} => ['abc']}