一、集合 Set
概念:Set 是一种无序唯一的数据结构,常用来做去重、判断某元素是否在集合中、求交集
特点:
- 由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),所以 keys 方法和 values 方法的行为完全一致
- Set 对象允许你储存任何类型的唯一值,无论是基本数据类型还是引用数据类型,向 Set 加入值的时候,不会发生类型转换,所以 5 和 "5" 是两个不同的值。Set 内部判断两个值是否不同,使用的算法叫做“Same-value-zero equality”,它类似于精确相等运算符(===),主要的区别是 NaN 等于自身,而精确相等运算符认为 NaN 不等于自身
// 集合创建
const mySet = new Set(['a', 'a', 'b'])
console.log(mySet) // {'a', 'b'}
--------------------------------------------------------------------------------
// 增删改查
// add(value) 添加某个值,返回 Set 结构本身(可以链式调用)
myset.add('c')
console.log(mySet) // {'a','b','c'}
// size属性 获取集合内容的个数(长度)
console.log(mySet.size) // 3
// delete(value) 删除某个值,返回一个布尔值,表示删除是否成功
mySet.has('b') // true
// has(value) 返回一个布尔值,表示该值是否为Set的成员
mySet.has('a') // true
// clear() 清除所有成员,没有返回值
// 求并集、交集、差集
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}
// (a 相对于 b 的)差集
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1}
二、WeakSet
WeakSet 对象允许你将弱引用对象储存在一个集合中
WeakSet 与 Set 的区别:
- WeakSet 只能储存对象引用,不能存放值,而 Set 对象都可以
- WeakSet 对象中储存的对象值都是被弱引用的,即垃圾回收机制不考虑 WeakSet 对该对象的应用,如果没有其他的变量或属性引用这个对象值,则这个对象将会被垃圾回收掉(不考虑该对象还存在于 WeakSet 中),所以 WeakSet 对象里有多少个成员元素,取决于垃圾回收机制有没有运行,运行前后成员个数可能不一致,遍历结束之后,有的成员可能取不到了(被垃圾回收了),WeakSet 对象是无法被遍历的(ES6 规定 WeakSet 不可遍历),也没有办法拿到它包含的所有元素
const arr = [[1, 2], [3, 4]]
const weakset = new WeakSet(arr)
console.log(weakset) // {[1,2], [3,4]}
var ws = new WeakSet()
var obj = {}
var foo = {}
ws.add(window)
ws.add(obj)
ws.has(window) // true
ws.has(foo) // false
ws.delete(window) // true
ws.has(window) // false
三、字典 Map
概念:Map 与集合类似,字典也是一种存储唯一值的数据结构,但是它是以键值对的形式来存储的,常用来做键值对的增删改查
特点:
- Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键。这就解决了同名属性碰撞(clash)的问题,扩展别人的库的时候,如果使用对象作为键名,就不用担心自己的属性与原作者的属性同名
Map 和 Object 的区别:
Object 的键只能是字符串或者 Symbols,但 Map 的键可以是任意类型的值;Map 的键值对个数可以从 size 属性获取,而 Object 的键值对个数只能手动计算
Map 和 Set 的区别:
Set 是以 [value, value]的形式储存元素,Map 是以 [key, value] 的形式储存
const m1 = new Map([['a', 1], ['b', 2]])
console.log(m1) // {"a" => 1, "b" => 2}
// set(key, val) 向Map中添加新元素
m1.set('c', 3)
console.log(m1) // {"a" => 1, "b" => 2, "c"=>3}
// get(key) 通过键值查找特定的数值并返回
console.log(m1.get('c')) //3
// has(key) 判断Map对象中是否有Key所对应的值,有返回true,否则返回false
console.log(m1.get('c')) //true
// delete(key) 通过键值从Map中移除对应的数据
m1.delete('c')
console.log(m1) // {"a" => 1, "b" => 2}
// clear() 将这个Map中的所有元素删除
四、WeakMap
WeakMap 对象是一组键值对的集合,其中的键是弱引用对象,而值可以是任意
WeakMap 中,每个键对自己所引用对象的引用都是弱引用,在没有其他引用和该键引用同一对象,这个对象将会被垃圾回收(相应的key则变成无效的),所以,WeakMap 的 key 是不可枚举的。
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);