ES6 详解之 Map Set Symbol

发布于 2021-12-15 21:09:36 字数 7643 浏览 1160 评论 0

ES6 提供了 值-值 对的数据结构,键名不仅可以是字符串,也可以是对象。它是一个更完善的 Hash 结构。

概述

1.键值对,键可以是对象

const map1 = new Map();
const objkey = {p1:'v1'};
map1.set(objkey,'hello');
console.log(map1.get(objkey)); // hello

2.Map 可以接受数组作为参数,数组成员还是一个数组,其中有两个元素,一个表示键一个表示值。

const map2 = new Map([['name','james'],['age',18],['profession','software']]);
console.log(map2.get('name')); // james
console.log(map2.get('age'));// 18

操作

1.size 获取 map 的大小长度

const map2 = new Map([['name','james'],['age',18],['profession','software']]);
console.log(map2.size); // 3

2.设置键值对,键可以是各种类型,包括 undefined,function 等

const map4 = new Map();
map4.set('k1',5);
map4.set(222,'哈哈哈');
map4.set(undefined,'ggggg');
const fun = function(){
    console.log('hello 我是方法');
}
map4.set(fun,'fun');
console.log('map4 size :%s',map4.size);  // 4
console.log('undefined value :%s',map4.get(undefined)); //ggggg
console.log('fun value:%s',map4.get(fun)); //fun

3.也可对 set 进行链式调用。

map4.set('k2', 2).set('k3', 4).set('k4', 5)

4.get 获取键对应的值

const map4 = new Map();
map4.set('k1',5);

5. has 判断键是否存在

const map5 = new Map();
map5.set(undefined,4);
console.log('map undefined:%s',map5.has(undefined)); //true
console.log('map k1:%s',map5.has('k1'));// false

6.delete 删除键值对

const map5 = new Map();
map5.set(undefined,4);
console.log('map undefined:%s',map5.has(undefined)); //true
map5.delete(undefined);
console.log('map undefined:%s',map5.has(undefined)); //false

7.clear 删除 map 中所有的键值对

const map5 = new Map();
map5.set('a','ad').set('b',111).set(3,333).set(fun,'demo');
console.log(map5.size); // 4
map5.clear();
console.log(map5.size); // 0

注意点:

如果 Map 的键是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等,Map 将其视为一个键,比如 0 和 -0 就是一个键,布尔值 true 和字符串 true 则是两个不同的键。另外, undefined 和 null 也是两个不同的键。虽然NaN不严格相等于自身,但 Map 将其视为同一个键,如下代码所示.

let map = new Map();

map.set(-0, 123);
map.get(+0) // 123

map.set(true, 1);
map.set('true', 2);
map.get(true) // 1

map.set(undefined, 3);
map.set(null, 4);
map.get(undefined) // 3

map.set(NaN, 123);
map.get(NaN) // 123

遍历

1.keys() 遍历 map 的所有 key

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

2.values() 遍历 map 的所有 value

for (let key of map5.values()) {
    console.log(key);
}

3.entries() 遍历 map 的所有键值对

方法一:

for (let item of map5.entries()) {
    console.log("key:%s, value:%s",item[0],item[1]);
}

方法二:

for(let [key,value] of map5.entries()) {
    console.log("key:%s, value:%s",key,value);
}

4.forEach 遍历 map 所有的键值对

map5.forEach(function(value,key,map){
    console.log("key:%s, value:%s, map:%s",key,value,map.size);
}); 

forEach 知识拓展

forEach 有第二个参数,可以用来绑定 this。

这样有个好处,map 的存储的数据和业务处理对象可以分离,业务处理对象可以尽可能的按职责分割的明确符合SRP原则。

const output = {
    log:function(key,value){
        console.log("key:%s,Value:%s",key,value);
    },
    say:function(){
        console.log("来打我呀");
    }
};

map5.forEach(function(key,value){
    this.log(key,value);
    this.say();
},output);

和其他结构的互转

1.Map To Array

使用扩展运算符 (...) 可将 map 内的元素都展开为数组

console.log(...map5);

(2) ["a", "ad"]0: "a"1: "ad"length: 2__proto__: Array(0) (2) ["b", 111] (2) [3, 333] (2) [ƒ, "demo"]

let arr = [...map5];
console.log(arr);
[...map5.keys()];
[...map5.values()];
[...map5.entries()];

(4) [Array(2), Array(2), Array(2), Array(2)]
0: (2) ["a", "ad"]
1: (2) ["b", 111]
2: (2) [3, 333]
3: (2) [ƒ, "demo"]
length: 4
__proto__: Array(0)

结合数组的 map 方法、filter方法,可以实现 Map 的遍历和过滤(Map 本身没有 map 和 filter 方法)。

const map0 = new Map()
.set(1,'a')
.set(2,'b')
.set(3,'c');

const map1 = new Map(
    [...map0].filter(([k,v])=>k<3)
);
// 产生map结构{1=>'a',2=>'b'};
const map2 = new Map(
    [...map0].map(([k,v])=>[k*2,'_'+v])
);
// 产生map结构{2 => "_a", 4 => "_b", 6 => "_c"}

2.Array To Map

使用数组来构造一个 map

const map6 = new Map([
    ['name','james'],
    ['age',26]
])

console.log(map6);

Map(2) {"name" => "james", "age" => 26}

3.Map To Object

写一个转换函数,遍历 map 的所有元素,将元素的键和值作为对象属性名和值写入 Object 中。

function mapToObject(map) {
    // 创建一个空对象
    let obj = {};
    for (let [k,v] of map) {
        obj[k] = v; 
    }
    return obj;
}
console.log(mapToObject(map6));

// {name: "james", age: 26}

4.Object To Map

同理,再写一个转换函数遍历 Object,将属性名和值作为键值对写入 Map。

function objectToMap(obj) {
    let map = new Map();
    for (let [k,v] of Object.entries(obj)){
        map.set(k,v);
    }
    return map;
}
let objs = mapToObject(map6);
console.log(objectToMap(objs));
// Map(2) {"name" => "james", "age" => 26}

注意点:

object 不能实现 for of 迭代循环,会报 'x' is not iterable 的 TypeError。

这个值作为 for…of 的表达式右值,或者作为一个函数的参数,如 Promise.all 或者 TypedArray.from, 不是一个 可迭代对象. 一个可迭代对象可以是一个内置可迭代类型,如 Array,String 或 Map,一个 generator 生成结果, 或者一个实现了可迭代协议的对象。

做为替代你必须使用 Object.keys

function objectToMap(obj) {
    let map = new Map();
    for (let k of Object.keys(obj)){
        map.set(k,obj[k]);
    }
    return map;
}

或 Object.entries 来迭代对象的属性或属性值.

function objectToMap(obj) {
    let map = new Map();
    for (let [k,v] of Object.entries(obj)){
        map.set(k,v);
    }
    return map;
}

5.set To map

将创建好的set在创建map的构造函数时,直接传入

const set = new Set([
    ['foo',1],
    ['bar',2]
]);
const map9 = new Map(set);
console.log(map9);
// Map(2) {"foo" => 1, "bar" => 2}

6.map To set

遍历map中的键值,然后add到set中

function mapToSet(map) {
    let set = new Set();
    for (let [k,v] of map) {
        set.add([k,v]);
    }
    return set;
}
// Set(2) {Array(2), Array(2)}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

归途

暂无简介

0 文章
0 评论
558 人气
更多

推荐作者

lorenzathorton8

文章 0 评论 0

Zero

文章 0 评论 0

萧瑟寒风

文章 0 评论 0

mylayout

文章 0 评论 0

tkewei

文章 0 评论 0

17818769742

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文