写点什么

ES6 之 map 方法

用户头像
法医
关注
发布于: 2 小时前
ES6之map方法

上集说到 ES6 中 set 方法,在 ES6 中除了增加 set 方法之外,还考虑到一种场景——键值对的存储,而map集合就是专门存储多个键值对(key value pair)的数据。


在 map 出现之前,我们使用的是对象的方式来存储键值对,键是属性名,值是属性值。键值对数据结合的特点就是:键不可重复。如果用对象来存储键值对在某些场景下不太如意:


  1. 键名只能是字符串或者符号,这就给它的使用带来很大的限制

  2. 获取数据的数量不方便,如果想知道对象中存了多少个数据,就必须先拿到所有的键名,然后通过求数组的长度才能知道对象中有多少个属性。

  3. 键名容易跟原型上的名称冲突。

如何创建 map


new Map();//创建一个没有任何内容的map集合
new Map(iterable);//创建一个具有初始化内容的map,初始内容来自于可迭代对象每一次迭代的结果,但是,它要求每一次迭代的结果必须是一个长度为2的数组,数组第一项表示键,数组第二项表示值
复制代码


例:创建一个没有任何内容的 map 集合


const mp = new Map();console.log(mp);
复制代码


执行结果:



例:创建一个有初始内容的 map 集合


const mp = new Map([["a",1],["b",2],["c",3]]);console.log(mp);
复制代码


执行结果:


如何进行后续操作


1、size:只读属性,获取当前 map 中键的数量


例:size


const mp = new Map([["a",1],["b",2],["c",3]]);console.log(mp);console.log("总数:",mp.size);
复制代码


执行结果:



2、set(键,值):设置一个键值对,键和值可以是任何类型这也是跟Object存储的区别,对象只能是字符串


例:set()


const mp = new Map([["a",1],["b",2],["c",3]]);mp.set("d",4)console.log(mp);
复制代码


执行结果:



注意点


  1. 如果键不存在,则添加一项

  2. 如果键存在,则修改它的值

  3. 判断键存不存在的方式与 set 相同,都为Object.is()


例:请问下面 map 中有几个值?


 const mp = new Map([["a",1],["b",2],["c",3]]);       mp.set({},4);       mp.set("a",abc);       map.set({},00);       console.log(mp);       console.log("总数:",mp.size);
复制代码


执行结果:



从结果看:有 5 个值,对象是引用值,它们的地址不同,所以不会覆盖,而 a 的原值 1 会被 abc 覆盖掉。如果说需要使用相同引用值对象,可以这样改:


const mp = new Map([["a",1],["b",2],["c",3]]);       const obj = {};       mp.set(obj,4);       mp.set("a","abc");       mp.set(obj,00);       console.log(mp);       console.log("总数:",mp.size);
复制代码


执行结果:



3、get(键):根据一个键,得到一个值


例:get(键)


const mp = new Map([["a",1],["b",2],["c",3]]);   console.log("get('a')",mp.get("a"));
复制代码


执行结果:



例:如果传入不存在的键


const mp = new Map([["a",1],["b",2],["c",3]]);   console.log("get('a')",mp.get("jasnbdjka"));
复制代码


执行结果:



4、has(键):判断某个键是否存在


例:has()


 const mp = new Map([["a",1],["b",2],["c",3]]);    console.log("has('a')",mp.has("a"));
复制代码


执行结果:



5、delete(键):删除指定的键,成功返回true,失败返回false


例:delete(键)


const mp = new Map([["a",1],["b",2],["c",3]]);   console.log("delete('a')",mp.delete("a"));
复制代码


执行结果:



6、clear():清空 map


例:clear()


const mp = new Map([["a",1],["b",2],["c",3]]);console.log(mp);
复制代码


如何与数组进行转换

例:数组转换成 map 集合


//直接把数组放到 new Map(数组)就可以了const mp = new Map(要转换的数组);//如下:const mp = new Map([["a",1],["b",2],["c",3]]);
复制代码


例:map 转换为数组


//map本身也是一个可迭代的对象,每次迭代的结果就是每一项的值const mp = new Map([["a",1],["b",2],["c",3]]);const arr = [...mp];console.log(arr);
复制代码


执行结果:


遍历

  1. 使用for of循环,每次迭代得到的是一个长度为 2 的数组


例:for of


   const mp = new Map([["a",1],["b",2],["c",3]]);        for (const item of mp) {        console.log(item);    }
复制代码


执行结果:



当然也可以直接解构


    const mp = new Map([["a",1],["b",2],["c",3]]);    //方式一:    for (const [key,value] of mp) {        console.log(key,value);    }    //方式二:    for (const item of mp) {        console.log(item[0],item[1]);    }
复制代码


执行结果:



  1. 使用forEach遍历


  • 参数 1:每一项的值

  • 参数 2:每一项的键

  • 参数 3:map 本身


例:forEach


  const mp = new Map([["a",1],["b",2],["c",3]]);        mp.forEach((value,key,that) =>{            console.log(value,key,that);        })
复制代码


执行结果:


手写 map

手写 map 方法跟浏览器提供的 map 方法是不一样的,因为我们没有办法调用底层代码,就当拓展思维了。


1、新建 myMap.js 文件


class MyMap {    constructor(iterable = []) {        //验证是否是可迭代的对象        this.isIterator(iterable);        this._datas = [];        for (const item of iterable) {            //item 也得是一个可迭代对象            this.isIterator(item);
//取出第一个迭代值和第二个迭代值 const iterator = item[Symbol.iterator](); const key = iterator.next().value; const value = iterator.next().value; this.set(key, value); }
} //判断是否是可迭代对象 isIterator(target) { if (typeof target[Symbol.iterator] !== "function") { throw new TypeError(`${typeof target} ${target} is not is not iterable (cannot read property Symbol(Symbol.iterator))`); } }
//set方法 set(key, value) { const obj = this._getObj(key); if (obj) { //如果存在键名,则修改值 obj.value = value; } else { this._datas.push({ key, value }) }
} //delete delete(key) { for (let i = 0; i < this._datas.length; i++) { const element = this._datas[i]; if (this.isEqual(element.key, key)) { this._datas.splice(i, 1); return true; } } return false; } //get方法 get(key) { const item = this._getObj(key); if (item) {
return item.value; } return undefined; }
//size方法 get size() { return this._datas.length; } //has方法 has(key) { return this._getObj(key) !== undefined; //不等于undefined,说明值找到了 } //clear方法 clear() { this._datas.length = 0; } //forEach forEach(callback) { for (const item of this._datas) { callback(item.value, item.key, this); } }
/** * 根据key值从内部数组中,找到对应的数组项 * @param {*} key */ _getObj(key) { for (const item of this._datas) { if (this.isEqual(item.key, key)) { return item; } } }
//使MyMap本身可迭代 *[Symbol.iterator]() { for (const item of this._datas) { yield [item.key, item.value] } }

/** * 判断两个数据是否相等 * @param {*} data1 * @param {*} data2 */ isEqual(data1, data2) { //如果data1和data2都等于0,那么我们认为它们相等 if (data1 === 0 && data2 === 0) { return true; } return Object.is(data1, data2); }
复制代码


代码测试:


<script src="./js/myMap.js"></script><script>    const mp = new MyMap([["a",1],["b",2],["c",3]]);    console.log(mp);</script>
复制代码


例:set 方法



例:forEach


<script src="./js/yMap.js"></script><script>    const mp = new MyMap([["a",1],["b",2],["c",3]]);    mp.forEach((value,key,that) => {        console.log(value,key,that);    });
</script>
复制代码


执行结果:



以上就是今天的分享了,希望可以帮到大家,我也是刚开始写技术文章,还有很多欠缺的地方,希望掘金大佬们多多指教,谢谢大家!!

发布于: 2 小时前阅读数: 3
用户头像

法医

关注

公众号@前端猎手 2020.07.17 加入

喜欢用写作记录自己技术成长过程

评论

发布
暂无评论
ES6之map方法