美文网首页
ES6 新特征之Map

ES6 新特征之Map

作者: 前白 | 来源:发表于2020-12-21 10:25 被阅读0次

    ES6 给我们提供了 Map 数据结构,它类似于对象,用于保存键值对。不同的是,Map 中键的范围不限于字符串类型,各种类型的值(包括对象)都可以当作一个键或一个值。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。如果需要用到“键值对”的数据结构,MapObject 更合适。

    Map和Object的区别

    • Object 中的键只能是字符串或者 Symbols 类型,但 Map 中的键可以是任意值。
    • Map 中的键值是有序的(FIFO 原则),而添加到对象中的键则不是。
    • Map 的键值对个数可以从 size 属性获取,而 Object 的键值对个数只能手动计算。
    • Object 都有自己的原型,原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。

    创建Map

    MapES6 提供给我们的构造函数,本质上是键值对的集合。任何值(对象或者原始值) 都可以作为一个键或一个值。

    示例:

    我们可以通过 Map() 方法来创建一个空 Map

    let map = new Map();
    console.log(map);  // 输出:Map {}
    

    上述代码中,我们可以在创建时初始化 Map 时,Map 可以接收数组作为参数,并且数组成员也是一个个数组,其中包含两个元素,一个表示键,一个表示值。

    示例:

    例如下面这个 Map 中有两个键值对:

    let map = new Map([["name","xkd"],['age','18']]);
    console.log(map);
    // 输出:Map { 'name' => 'xkd', 'age' => '18' }
    

    第一个键值对中键为 name,值为 xkd,第二个键值对中键为 age,值为 18

    Map的方法和属性

    set()方法

    set() 方法用于设置所对应的键值对,然后返回整个 Map 结构,如果已经有值,则键值会被更新,否则就会生成新的键。

    示例:
    let map = new Map();
    map.set('name', 'xkd');
    console.log(map);  // 输出:Map { 'name' => 'xkd' }
    

    如果要设置多个键值对,则可以执行多次 set 方法。

    示例:

    例如向 map 中添加三个键值对:

    let map = new Map();
    map.set('a', 1);
    map.set('b', 2);
    map.set('c', 3);
    console.log(map);  
    // 输出:Map { 'a' => 1, 'b' => 2, 'c' => 3 }
    

    get()方法

    get() 方法用于读取 key 对应的键值,如果找不到 key,则返回 undefined

    示例:

    下面代码中我们通过 set() 方法为 Map 设置键值对,然后通过 get() 方法获取指定键对应的值:

    let map = new Map();
    map.set('a', 1);
    map.set('b', 2);
    map.set('c', 3);
    
    console.log(map.get('a'));  // 输出:1
    console.log(map.get('b'));  // 输出:2
    console.log(map.get('c'));  // 输出:3
    console.log(map.get('d'));  // 输出:undefined
    

    可以看到,如果我们想要取读取的键值在 map 中不存在,例如 d,那么最终会输出 undefined

    has()方法

    has() 方法返回一个布尔值,表示某个键是否在 Map 数据结构中。在则返回 true,不在则返回 false

    示例:
    let map = new Map();
    map.set('a', 1);
    map.set('b', 2);
    map.set('c', 3);
    
    console.log(map.has('a'));    // 输出:true
    console.log(map.has('b'));    // 输出:true
    console.log(map.has('name')); // 输出:false
    

    上述代码中,我们先通过 set() 方法 向 map 中添加了三个键值对,但是很明显 ab 存在 map 数据结构中,而 name 不存在。

    delete()方法

    delete() 方法用于删除某个键,删除成功返回 true,如果删除失败则返回 false

    示例:
    let map = new Map();
    map.set('a', 1);
    map.set('b', 2);
    map.set('c', 3);
    
    console.log(map.delete("a"));    // 输出:true
    console.log(map.delete("age"));  // 输出:false
    

    可以看到,因为 amap 中的键,所以删除 a 时返回 true 值。而 age 不是 map 中的键,所以返回 false

    clear()方法

    clear() 方法用于清除 Map 中所有成员,没有返回值。

    示例:

    Map 中的成员很多是,如果使用 delete() 方法一个键一个键删除会很麻烦,所以如果要清除 Map 中所有的成员,可以直接使用 clear() 方法:

    let map = new Map();
    map.set('a', 1);
    map.set('b', 2);
    map.set('c', 3);
    
    map.clear();
    console.log(map);  // 输出:Map {}
    

    size属性

    size 属性可以用于返回 Map 中成员总数。

    示例:
    let map = new Map();
    map.set('a', 1);
    map.set('b', 2);
    map.set('c', 3);
    
    console.log(map.size);  // 输出:3
    

    Map 遍历方法

    Map 原生提供三个遍历器生成函数和一个遍历方法。

    示例:

    我们先创建并初始化一个 Map

    let map1 = new Map([
        ["x", 1],
        ["k", 2],
        ["d", 3]
    ]);
    

    keys()方法

    keys() 方法是一个用于返回键名的遍历器。

    示例:

    例如通过 keys() 方法遍历 map1

    for(let key of map1.keys()){
        console.log(key);
    }
    

    输出:

    x
    k
    d
    

    从上述输出中可以看出,成功遍历了 map1 中的所有键值。

    values()方法

    values() 方法与 keys() 对应,是一个用于返回键值的遍历器。

    示例:

    例如通过 values() 方法遍历 map1

    for(let v of map1.values()){
        console.log(v);
    }
    

    输出:

    1
    2
    3
    

    entries()方法

    如果我们又想要遍历 Map 中的键又想要遍历 Map 中的值,可以使用 entries() 方法,entries() 方法用于返回所有成员的遍历器。

    示例:
    let map1 = new Map([
        ["x", 1],
        ["k", 2],
        ["d", 3]
    ]);
    for(let [key,value] of map1.entries()){
        console.log(key+':'+value);
    }
    

    输出:

    x:1
    k:2
    d:3
    

    forEach()方法

    forEach() 方法用于遍历 Map 的所有成员,第二个参数绑定 this

    示例:
    map1.forEach(function(value, key){
        console.log(key+':'+value);
    });
    

    输出:

    x:1
    k:2
    d:3
    

    Map的类型转换

    Map 类型可以与其他的数据类型进行转换,我们一起来看一下。

    示例:
    • Map 转为数组类型:可以使用扩展运算符... 来实现。
    let map1 = new Map();
    map1.set("name", "xkd");
    console.log([...map1]);  
    // 输出:[ [ 'name', 'xkd' ] ]
    
    • 数组类型转为 Map :将数组传入 Map 构造函数即可。
    let map1 = new Map([
        ["x", 1],
        ["k", 2],
        ["d", 3]
    ]);
    
    • Map 转为对象:如果所有 Map 的键都是字符串,它可以无损地转为对象。如果有非字符串的键名,那么这个键名会被转成字符串,再作为对象的键名。
    function strMapToObj(strMap) {
        let obj = Object.create(null);
        for (let [k,v] of strMap) {
          obj[k] = v;
        }
        return obj;
    }
      
    let map1 = new Map();
    map1.set("name", "xkd");
    console.log(strMapToObj(map1));  
    // 输出:[Object: null prototype] { name: 'xkd' }
    
    • 对象转为 Map:可以使用 Object.entries() 方法来实现。
    let obj = {"a":1, "b":2};
    let map1 = new Map(Object.entries(obj));
    console.log(map1); 
    // 输出:Map { 'a' => 1, 'b' => 2 }
    
    • Map 转为 JSON:分为两种情况,一种是 Map 键名为字符串,这可以转为对象 JSON
    function strMapToObj(strMap) {
        let obj = Object.create(null);
        for (let [k,v] of strMap) {
          obj[k] = v;
        }
        return obj;
    }
    
    function strMapToJson(strMap) {
        return JSON.stringify(strMapToObj(strMap));
    }
      
    let map1 = new Map().set('a', 1).set('b', 2);
    console.log(strMapToJson(map1)); // 输出:{"a":1,"b":2}
    

    还有一种情况是,Map 中的键名有非字符串,这时可以选择转为数组 JSON

    function mapToArrayJson(map) {
        return JSON.stringify([...map]);
    }
      
    let map1 = new Map().set(true, 1).set({b: 2}, 2);
    console.log(mapToArrayJson(map1));  // 输出:[[true,1],[{"b":2},2]]
    
    • JSON 转为 Map:如果所有键名都是字符串则可以像下面这个。
    function objToStrMap(obj) {
        let strMap = new Map();
        for (let k of Object.keys(obj)) {
          strMap.set(k, obj[k]);
        }
        return strMap;
    }
    function jsonToStrMap(jsonStr) {
        return objToStrMap(JSON.parse(jsonStr));
    }
      
    console.log(jsonToStrMap('{"a": 1, "b": 2}'));  
    // 输出:Map { 'a' => 1, 'b' => 2 }
    

    如果整个 JSON 就是一个数组,且每个数组成员本身,又是一个有两个成员的数组。它可以一一对应地转为 Map。这往往是 Map 转为数组 JSON 的逆操作。

    function jsonToMap(jsonStr) {
        return new Map(JSON.parse(jsonStr));
    }
      
    console.log(jsonToMap('[[1, 100],[{"age":18},[20]]]'));
    // 输出:Map { 1 => 100, { age: 18 } => [ 20 ] }
    

    链接:https://www.9xkd.com/

    相关文章

      网友评论

          本文标题:ES6 新特征之Map

          本文链接:https://www.haomeiwen.com/subject/ngqrnktx.html