前言

基础不牢地动山摇吃不好饭睡不好觉。

↓一些之前没提到的有趣数据结构和API。

Set集合&Map映射

众所周知,Object类型是一种万能数据结构,可以把字符串映射为任意值。但是这明显限制了映射和集合的发挥(字符串的约束+不必要的toString属性)。ES6新增了两类数据结构↓

Set

特点

  • 没有索引
  • 不重复
  • 可迭代(for/of√;forEach(val)√)
  • 非常之快

创建

1
2
let set = new Set()
let set1 = new Set([1, 'w']) // 构造函数参数必须是可迭代对象(包括其他集合)

属性

1
let len = set .size // 获取集合长度,确实有点像数组的length属性

方法

1
2
3
4
let s = new Set([1, 2, 3])
s.add(1) // 增 => [1, 2, 3]
s.delete(1) // 删 => false
s.has(1) // 查 => false

需要注意的是:Set成员根据严格相等===判断重复。因此,如果值是对象类型的话,也会根据全等来判重,所以如果我们↓

1
2
3
4
let arr = [1, 2, 3]
let s = new Set()
s.add(arr)
s.delete([1, 2, 3]) // false

是删不掉s中的arr的!如果真想删的话,需要保证delete传入参数的引用与arr引用相同。不过遇到这种,我们一般会提前对数组进行一些原始值化操作(个人理解),比如let str = arr.join('-'); s.add(str)

集合之于数组

集合专门为成员测试做了优化(具体啥优化咱不清楚),has()速度非常之快,这比数组的执行速度和数组大小成反比includes(),快!

Map

特点

  • 键值映射
  • 可迭代(forEach((val, key) => …)这个顺序一定记得用的时候颠过来√;for [key, val] of map这个顺序√)
  • 非常之快

创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let map = new Map()

let map1 = new Map([ // 参数可以为一个可迭代对象
['one', 1],
['two', 2]
])
console.log(map1) // Map(2) { 'one' => 1, 'two' => 2 }

let obj = {
a: 1,
b: 2,
c: 3
}
let map2 = new Map(Object.entries(obj))
console.log(map2) // => Map(3) { 'a' => 1, 'b' => 2, 'c' => 3 }
console.log(map2.has('a')) // => true

(废话:起初用codepen在线编辑器进行的输出测试,结果map全输出空,我很疑惑,然后用本地node环境跑,输出正常了…还得是本地啊!)

属性

1
map.size // map大小

方法

1
2
3
4
5
6
7
8
9
10
let obj = {
a: 1,
b: 2,
c: 3
}
let map = new Map(Object.entries(obj))
map.set('d', 4) // 增
map.has('a') // 查
map.get('a') // 拿
map.delete('a') // 删

映射之于数组

同样也是啪的一下很快。

WeakSet & WeakMap

奇妙变体之——弱集合&若映射。

为啥是‘弱’呢?

因为它们不会阻止键值被当做垃圾收集。(说实话我看这句解释后就像看到了这句解释)

发现了一个大坑——垃圾回收机制(另开一节吧,看吧好多空文章就是这么来的5555)。不过让我们先接着看解释↓

WeakMap不会阻止键值被当做垃圾收集。垃圾收集是JS解释器回收内存空间的过程,凡是因无法访问而无法被使用的对象都会被当做垃圾回收。常规映射对自己的键值对保持着比较强的引用,所以及时它那些引用不存在了,也可以通过映射来访问键。但是WeakMap就不一样了,它是弱引用,所以说没了就真的拿不到了。WeakSet同理。

创建/属性/算法

弱哥们俩和强哥们俩在构造函数使用上有差别。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let set = WeakSet() // 不能传参
let map = WeakMap() // 不能传参

// 弱哥们俩都没有size

// set的三个用法(仅)
set.add(非原始值)
set.has(...)
set.delete(...)
// map的四个用法(仅)
map.get()
map.set(key, 非原始值)
map.has()
map.delete()

场景

暂时能想到的有:我想给一些对象打标记,可以扔在一个WeakSet里。

书中:WeakMap的话,主要是实现值与对象的关联而不导致内存泄漏,但是我想不到例子。。。

TypedArray定型数组