Map
简介
Map
数据结构类似于 JavaScript
中的对象
,不过对象的键只能是字符串, Map 的键可以是任意类型的值
。需要注意的是,Map 的键是跟内存地址绑定的,因此有些看似相同的键,值却是不一样的,这一点会在下文举例说明。
Map
的键和内存地址绑定带来的好处是避免了同名属性碰撞/冲突问题,因此我们在对别人的库进行扩展时,不用担心会破坏原本的值。
Map 可以接受一个数组作为参数,但该数组的成员需要是一个个表示键值对的数组。
const map = new Map([
['name', '张三'],
['age', '18']
]);
// {'name': '张三', 'age': '18'}
操作方法
map.has('name') // 判断是否存在某个键,返回true/false
map.get('name') // 获取某个键的值,如果不存在,则返回 undefined
map.set('sex', '男') // 添加成员,如果添加重复的键,会覆盖已存在的值
map.delete('sex') // 删除某个值,成功返回 true,失败返回 false
Map 的键是和内存绑定的,这一点要尤其注意。仔细观察下面的两组示例:
必须严格等于的两个值,Map 才会将它们视为同一个键,NaN 除外。
const map = new Map();
map.set(['a'], 666);
map.get(['a']) // undefined
const map = new Map();
const a = ['a']
map.set(a, 666);
map.get(a) // 666
遍历
Map
也可以像数组一样遍历,但是操作方法有所区别,只能用 keys()
,values()
,entries()
,forEach()
等方法来遍历。默认遍历器接口是 entries
。
const map = new Map([
['name', '张三'],
['age', '18']
]);
for (let item of map.keys()) {
console.log(item);
}
// 'name'
// 'age'
for (let item of map.values()) {
console.log(item);
}
// '张三'
// '18'
for (let item of map.entries()) {
console.log(item);
}
// ['name', '张三']
// ['age', '18']
for (let [key, value] of map.entries()) {
console.log(key, value);
}
// 'name' '张三'
// 'age' '18'
for (let [key, value] of map) {
console.log(key, value);
}
// 'name' '张三'
// 'age' '18'
map.forEach(function(value, key, map) {});
WeakMap
简介
WeakMap
与 Map
类似,不过键只能是对象
或者 null
,不可以是其它类型,同时,WeakMap 中的成员是弱引用,不影响垃圾回收机制。
Set
简介
Set
是 ES6
提供的一种新的数据结构,,类似于数组结构,它的键和值是同一个,且它的值都是唯一且不重复的。
Set
本身是一个构造函数,用来生成 Set
数据结构。向 Set
添加值的时候,被添加的值类型不会发生改变。
Set
可以接受一个数组作为参数来进行初始化。
const set = new Set([1, 2, 3, 4, 4, 4]);
[...set] // [1, 2, 3, 4]
添加成员
可以通过 add()
方法向 Set 添加成员,注意,无法添加重复的成员。
const set = new Set([1, 2, 3, 4, 4, 4]);
set.add(1) // {1, 2, 3, 4}
set.add(5) // {1, 2, 3, 4, 5}
修改成员
Set
本身没有方法修改成员,但是可以通过其它途径来进行修改,比如映射一个新的 Set 。
let set = new Set([1, 2, 3]);
set = new Set([...set].map(val => val * 2));
// {2, 4, 6}
操作方法
Set
的一些其它方法。
const set = new Set([1, 2, 3, 4, 4, 4]);
set.add(5) // 添加成员
set.delete(1) // 删除成员
set.has(5) // 判断成员是否存在,返回 true/false
set.clear() // 清空所有成员
遍历
Set
也可以像数组一样遍历,但是操作方法有所区别,只能用 keys()
,values()
,entries()
,forEach()
等方法来遍历。
const set = new Set([1, 2, 3]);
for (let item of set.keys()) {
console.log(item);
}
// 1
// 2
// 3
for (let item of set.values()) {
console.log(item);
}
// 1
// 2
// 3
for (let item of set.entries()) {
console.log(item);
}
// [1, 1]
// [2, 2]
// [3, 3]
set.forEach((value, key) => console.log(key + ' : ' + value))
// 1 : 1
// 2 : 2
// 3 : 3
交集、并集、差集
利用遍历及 Set
数据类型不会有重复值的特性,可以轻松获取交集、并集、差集。
const a = new Set([1, 2, 3]);
const b = new Set([3, 4, 5]);
// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// set {3}
// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4, 5}
// 差集
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1, 2, 4, 5}
WeakSet
简介
WeakSet
类似于 Set
,也是不重复的值的集合,但是 WeakSet 的值只能是对象(非对象会报错),且 WeakSet 中的对象都是弱引用。
垃圾回收机制不会考虑 WeakSet 对对象的引用,如果没有其它地方存在对 WeakSet 中的对象引用,那么垃圾回收就会清理掉 WeakSet 中的对象。
const ws = new WeakSet([[1, 2], [3, 4]]);
// {[1, 2], [3, 4]}
操作方法
const ws = new WeakSet();
const obj = {};
ws.add(obj) // 添加成员
ws.delete(obj) // 删除成员
ws.has(obj) // 判断成员是否存在,返回 true/false
注意:WeakSet 无法遍历。
END