ES6 详解之 Map Set Symbol
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 技术交流群。
上一篇: ES6 详解 Proxy 拦截器/代理
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论