ES6 :Set/Map
Posted jony-it
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES6 :Set/Map相关的知识,希望对你有一定的参考价值。
Set:
类似数组,但是成员值是唯一的。
Set 函数可以接收一个数组(具有iterable接口的其他数据结构)
// 例一 const set = new Set([1, 2, 3, 4, 4]); [...set] // [1, 2, 3, 4] // 例二 const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]); items.size // 5 // 例三 const set = new Set(document.querySelectorAll(‘div‘)); set.size // 56 // 类似于 const set = new Set(); document .querySelectorAll(‘div‘) .forEach(div => set.add(div)); set.size // 56
去除数组重复:
去除字符串重复字符
[...new Set(‘ababbc‘)].join(‘‘) // "abc"
向 Set 加入值的时候,不会发生类型转换,所以5
和"5"
是两个不同的值。Set 内部判断两个值是否不同,使用的算法叫做“Same-value-zero equality”,它类似于精确相等运算符(===
),主要的区别是NaN
等于自身,而精确相等运算符认为NaN
不等于自身。
另外,对于对象需要特别注意。
实例方法:
add(value)
:添加某个值,返回 Set 结构本身。delete(value)
:删除某个值,返回一个布尔值,表示删除是否成功。has(value)
:返回一个布尔值,表示该值是否为Set
的成员。clear()
:清除所有成员,没有返回值。
s.add(1).add(2).add(2); // 注意2被加入了两次 s.size // 2 s.has(1) // true s.has(2) // true s.has(3) // false s.delete(2); s.has(2) // false
对比对象判断键
// 对象的写法 const properties = { ‘width‘: 1, ‘height‘: 1 }; if (properties[someName]) { // do something } // Set的写法 const properties = new Set(); properties.add(‘width‘); properties.add(‘height‘); if (properties.has(someName)) { // do something }
Array.from 转换为数组(类似数组和数组):
类似使用扩展运算符去除重复键
遍历方法:
keys()
:返回键名的遍历器values()
:返回键值的遍历器entries()
:返回键值对的遍历器forEach()
:使用回调函数遍历每个成员
有点类似对象中的方法,多了forEach:
keys:
keys
方法、values
方法、entries
方法返回的都是遍历器对象(详见《Iterator 对象》一章)。由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),所以keys
方法和values
方法的行为完全一致。
由于Set 部署了Symbol.iteartor 所以也就可以使用forEach 和 for of 方法:
forEach
方法还可以有第二个参数,表示绑定处理函数内部的this
对象。
扩展运算符(...
)内部使用for...of
循环。
实现并集(Union)、交集(Intersect)和差集(Difference):
let a = new Set([1, 2, 3]); let b = new Set([4, 3, 2]); // 并集 let union = new Set([...a, ...b]); // Set {1, 2, 3, 4} // 交集 let intersect = new Set([...a].filter(x => b.has(x))); // set {2, 3} // 差集 let difference = new Set([...a].filter(x => !b.has(x))); // Set {1}
改变Set结构:
// 方法一 let set = new Set([1, 2, 3]); set = new Set([...set].map(val => val * 2)); // set的值是2, 4, 6 // 方法二 let set = new Set([1, 2, 3]); set = new Set(Array.from(set, val => val * 2)); // set的值是2, 4, 6
WeakSet 结构:
它与 Set 有两个区别。
首先,WeakSet 的成员只能是对象,而不能是其他类型的值。其次,WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。
WeakSet 适合临时存放一组对象,以及存放跟对象绑定的信息。只要这些对象在外部消失,它在 WeakSet 里面的引用就会自动消失。(WeakSet 不可遍历)
Map:
Object 本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制.
Map 类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
const m = new Map(); const o = {p: ‘Hello World‘}; m.set(o, ‘content‘) m.get(o) // "content" m.has(o) // true m.delete(o) // true m.has(o) // false
接收数组(数组转map):
set/map:
const set = new Set([ [‘foo‘, 1], [‘bar‘, 2] ]); const m1 = new Map(set); m1.get(‘foo‘) // 1 const m2 = new Map([[‘baz‘, 3]]); const m3 = new Map(m2); m3.get(‘baz‘) // 3
如果读取一个未知的键,则返回undefined
:
new Map().get(‘asfddfsasadf‘) // undefined
1.size: 成员数
2.set(key,value): 不是put 哦
3.get(key): 获取
4.has(key):是否在当前Map中
5.delete(key):删除某个键
6.clear:清空
遍历方法:(跟set一样)
keys()
:返回键名的遍历器。values()
:返回键值的遍历器。entries()
:返回所有成员的遍历器。forEach()
:遍历 Map 的所有成员。
// 等同于使用map.entries() for (let [key, value] of map) { console.log(key, value); }
map[Symbol.iterator] === map.entries
// true
forEach:回调函数包涵三个参数,并且本身可以有第二个参数用来绑定this
数据结构转换:
Map转数组:
数组转Map
Map转对象:
function strMapToObj(strMap) { let obj = Object.create(null); for (let [k,v] of strMap) { obj[k] = v; } return obj; }
对象转Map:
function objToStrMap(obj) {
let strMap = new Map();
for (let k of Object.keys(obj)) {
strMap.set(k, obj[k]);
}
return strMap;
}
Map 转json:转换为对象后再转换为json
function strMapToJson(strMap) { return JSON.stringify(strMapToObj(strMap)); }
Map 的键名有非字符串,这时可以选择转为数组 JSON。
function mapToArrayJson(map) { return JSON.stringify([...map]); }
json 转map:先转换为对象,然后再转换为map
function jsonToStrMap(jsonStr) { return objToStrMap(JSON.parse(jsonStr)); }
WeakMap:整体类似map,但是与weakset一样,不能循环,并且只接收对象作为键名,指向的对象也不计入垃圾回收机制。
用途:
let myElement = document.getElementById(‘logo‘); let myWeakmap = new WeakMap(); myWeakmap.set(myElement, {timesClicked: 0}); myElement.addEventListener(‘click‘, function() { let logoData = myWeakmap.get(myElement); logoData.timesClicked++; }, false);
myElement
是一个 DOM 节点,每当发生click
事件,就更新一下状态。我们将这个状态作为键值放在 WeakMap 里,对应的键名就是myElement
。一旦这个 DOM 节点删除,该状态就会自动消失,不存在内存泄漏风险。
以上是关于ES6 :Set/Map的主要内容,如果未能解决你的问题,请参考以下文章