1. 程式人生 > >ES6新增 Map

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']}