• ES6的Map类型


    本文内容

    • Map的基本使用
    • Map支持的数据类型
    • Map的迭代
    • Map与其他对象的转化

    在Map出现之前,要实现类似需求,只能使用Object,但是Object还是存在一些问题的。

    • 如果使用Object作为key存储在{}中,key最终是当做[object Object]来使用的
    • Object的keys是无序的
    • 无法安全遍历Object
    • 无法直接获取Object大小
    Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。

    基本操作

    new Map([iterator])
    • iterator <Iterator> 可以是一个数组或者其他iterator对象,其元素为键值对(如['key', 'value'])。
    • null或undefined不会生效,返回一个空的Map
    • 非iterator会抛出错误 TypeError: object is not iterable
    const map = new Map();
    // Create
    map.set('name','xialei');
    map.set('site', 'https://www.ddhigh.com');
    // Update
    map.set('name', 'xialeistudio');
    // Read
    map.get('name');
    // Delete
    map.delete('name');
    // 清空
    map.clear();
    // map大小
    console.log(map.size);

    数据类型测试

    js中基本数据类型有string、number、boolean、null、undefined、symbol,复杂数据类型有object(包括object,array,function等),还有个特殊的NaN(typeof结果是number),分别对这些类型进行测试

    const map = new Map();
    const sKey = 'key',
        nKey = 1,
        bKey = true,
        nullKey = null,
        uKey = undefined,
        symbolKey = Symbol("key"),
        oKey = {},
        ooKey = oKey,
        aKey = [],
        fKey = function () { },
        nanKey = NaN;
    
    map.set(sKey, "string")
        .set(nKey, "number")
        .set(bKey, "boolean")
        .set(nullKey, "null")
        .set(uKey, "undefined")
        .set(symbolKey, "symbol")
        .set(oKey, "object")
        .set(aKey, "array")
        .set(fKey, "function")
        .set(nanKey, "NaN");
    
    console.log(map);
    console.log(map.get(sKey) === "string", map.get("key") === "string");
    console.log(map.get(nKey) === "number", map.get(1) === "number");
    console.log(map.get(bKey) === "boolean", map.get(true) === "boolean");
    console.log(map.get(nullKey) === "null", map.get(null) === "null");
    console.log(map.get(uKey) === "undefined", map.get(undefined) === "undefined");
    console.log(map.get(symbolKey) === "symbol");
    console.log(map.get(oKey) === "object", map.get({}) === "object", map.get(oKey) === map.get(ooKey));
    console.log(map.get(aKey) === "array", map.get([]) === "array");
    console.log(map.get(fKey) === "function", map.get(function () { }) === "function");
    console.log(map.get(nanKey) === "NaN", map.get(NaN) === "NaN");

    输出如下

    Map {
      'key' => 'string',
      1 => 'number',
      true => 'boolean',
      null => 'null',
      undefined => 'undefined',
      Symbol(key) => 'symbol',
      {} => 'object',
      [] => 'array',
      [Function: fKey] => 'function',
      NaN => 'NaN'
    }
    true true
    true true
    true true
    true true
    true true
    true
    true false true
    true false
    true false
    true true

    结论

    • string/number/boolean/null/undefined/NaN 按值存储,值一致即可访问
    • symbol必须是同一个Symbol才能访问
    • object/array/function等Object类型按照引用访问,必须是同一个引用才可以访问
    • Map是有序的,按照插入顺序
    • Map.set方法支持链式操作

    Map的迭代

    for...of

    同时迭代键值

    // 普通版本
    const map = new Map();
    map.set("1", 1);
    map.set("2", 2);
    
    for (const [k, v] of map) {
        console.log(k, v);
    }
    // 迭代器版本
    const map = new Map();
    map.set("1", 1);
    map.set("2", 2);
    
    for (const [k, v] of map.entries()) {
        console.log(k, v);
    }

    迭代键

    // 普通版本
    const map = new Map();
    map.set("1", 1);
    map.set("2", 2);
    
    for (const k of map.keys()) {
        console.log(k, map.get(k));
    }
    // 迭代器版本
    const map = new Map();
    map.set("1", 1);
    map.set("2", 2);
    
    for (const [k] of map.entries()) { // 解构赋值
        console.log(k, map.get(k));
    }

    迭代值

    // 普通版本
    const map = new Map();
    map.set("1", 1);
    map.set("2", 2);
    
    for (const v of map.values()) {
        console.log(v);
    }
    // 迭代器版本
    const map = new Map();
    map.set("1", 1);
    map.set("2", 2);
    
    for (const [,v] of map.entries()) {
        console.log(v);
    }

    forEach()

    forEach方法的顺序是value, key,不是key, value!
    const map = new Map();
    map.set("1", 1);
    map.set("2", 2);
    
    map.forEach((value, key) => {
        console.log(value, key);
    });

    Map与其他类型的转换

    Map与Object

    const obj = {
        name: 'xialei',
        site: 'https://www.ddhigh.com'
    };
    const map = new Map(obj);
    console.log(map);

    执行报错TypeError: object is not iterable,因为Object不是可迭代对象。

    可迭代对象:ES6新出的语法,对象或对象的原型链实现了Symbol.iterator方法,关于迭代器的内容将在下一篇文章中详细介绍

    我们给Object.prototype添加属性方法来支持迭代:

    warning: 正式代码请谨慎修改原型链!
    const obj = {
        name: 'xialei',
        site: 'https://www.ddhigh.com'
    };
    
    Object.prototype[Symbol.iterator] = function () { // Symbol.iterator可以理解为全局唯一的标识
        const keys = Object.keys(this);
        let keyIndex = 0;
    
        return {
            next() {
                if (keyIndex < keys.length) {
                    const key = keys[keyIndex++];
                    return { value: [key, obj[key]] }; // 迭代值
                }
                return { done: true }; // 迭代结束
            }
        }
    };
    
    const map = new Map(obj);
    console.log(map);

    Map与数组

    只支持[[key, value]]这种二维数组。二维数组的每一个元素包含key和value两个子元素  

    const map = new Map([['name', 'xialeistudio'], ['site', 'https://www.ddhigh.com']]);

    Map与Map

    由于Map是可迭代对象,因此可以作为参数传给Map构造函数

    两个Map的元素是一样的,不是Map不相等,因为不是同一个对象

    const map = new Map([['name', 'xialeistudio'], ['site', 'https://www.ddhigh.com']]);
    const map2 = new Map(map);
    
    console.log(map === map2); // false

    资源搜索网站大全 https://www.renrenfan.com.cn 广州VI设计公司https://www.houdianzi.com

    Map的合并

    多个Map可以合并,相同key会被覆盖,规则为后面的覆盖前面的  

    const map = new Map([
        [1, 1],
        [2, 2]
    ]);
    const map2 = new Map([
        [1, 2]
    ]);
    
    const map3 = new Map([...map, ...map2]);
    console.log(map3); // Map { 1 => 2, 2 => 2 }

    总结

    Map的出现解决了传统object无法直接解决的问题,更好地向标准编程语言靠近(标准编程语言一般会提供Map集合),使用的坑也比较少(比如没有object作为key时转换为[object Object]的问题)。

  • 相关阅读:
    币圈寒冬,过去两周内全球约60万矿商关机
    币圈人警惕!5大错误足以摧毁你的一切
    Doctype作用?标准模式与兼容模式各有什么区别?
    递归
    anguments
    fixed 和 absolute 定位的区别
    SublimeText 自带格式化代码功能
    css布局-双飞翼布局
    CSS布局-圣杯布局
    品字布局
  • 原文地址:https://www.cnblogs.com/qianxiaox/p/14113731.html
Copyright © 2020-2023  润新知