特性

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);
  1. 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)}

7.Map 转为 JSON
Map 转为 JSON 要区分两种情况。一种情况是,Map 的键名都是字符串,这时可以选择转为对象 JSON。

0 条评论
作者
状态
标签
二维码
目录