重读JavaScript高级程序设计,反向碾压面试官?
这是第六章的内容,集合引用类型。第五章讲的是Date、RegExp这些基本引用类型的用法,书里讲的都是基础API,基本每天都在用,就跳过去不写笔记了。Map和Set是ES6的新增特性,都1202年了我竟然还没用过,必须好好学习了!
Map
字面理解就是用来存储键值对的一种集合类型。那Object可以很方便的完成同样的功能,为什么还要有Map呢?
Map和Object性能比较
- 内存占用:给固定大小的内存,Map大约可以比Object多存储50%的键值对
- 插入性能:插入Map会稍微快一点,如果进行大量的插入操作,推荐使用Map
- 查找速度:如果涉及到大量查找操作,推荐使用Object
- 删除性能:Map的delete操作会更快,如果代码涉及大量的删除操作,推荐使用Map。(Object delete操作性能较差,但我们常常将属性值设置为null或undefined来进行伪删除)
Map的基本API
便于以后当文档翻,搬一下文档
// 初始化
const m = new Map(
[
['key', 'value'],
['key1', 'value1']
]
)
// set
m.set('key2', 'value2')
// has
m.has('key2') // true
// get
m.get('key2') // value2
// size
m.size // 3
// delete
m.delete('key2')
复制代码
Map和Object还有什么差异
- Object只能使用数值、字符串或符号作为键。Map可以使用任何javacript数据类型做为键
- Map会维护键值对的插入顺序,可以根据插入顺序执行迭代操作
WeakMap
WeakMap是Map的兄弟类型,它的API是Map的子集。
与Map不同的是,WeakMap的键只能是Object或者继承自Object的类型。如果使用非对象作为键会报错RypeError
WeakMap的关键特点
- WeakMap的键不属于正式的引用,不会阻止垃圾回收!一旦键被回收了,值本身也被回收了!
- WeakMap不支持迭代键值对的能力。因为WeakMap中的键值对任何时候都可能被销毁,因此也没有clear方法。
因为无法迭代,我们也不可能在不知道键对象引用的情况下从WeakMap中取值了!
来自书里的例子:
const wm = new WeakMap()
wm.set({}, "val")
// 因为没有指向这个键的其它引用,当这行代码执行完后,键就被回收了。值也跟着被回收了。
复制代码
WeakMap的应用场景:保存关联元数据
例子:
const wm = new WeakMap();
const loginButton = document.querySelector('#login')
wm.set(loginButton, {disable: true})
复制代码
一旦原来的DOM节点被销毁了,又没有其它地方引用这个对象,保存在WeakMap里的内容也对应的被销毁了。
Set
另一种新的集合类型,Set在很多方面都像是加强的Map。
Set基本API
// 初始化
const s = new Set(
[
'val1',
'val2'
]
)
// set
s.add('val3')
// has
s.has('val2') // true
// size
s.size // 3
// delete 返回一个布尔值,表示集合中是否存在要删除的值
s.delete('val2')
//clear 销毁所有值
s.clear()
复制代码
Set的特点
- Set可以包含任何数据类型作为值。会使用严格对象相等标准来检查值的匹配性
- Set会维护值插入时的顺序,支持按顺序迭代
const s = new Set(['val1', 'val2'])
for (let value of s.values()) {
// value
}
s.forEach((val, dupVal) => {
//
})
// 使用扩展运算符,把集合转换为数组
[...s]
复制代码
- 修改集合中值的属性,不会影响其作为集合值的身份
WeakSet
WeakSet是Set的兄弟类型,它的API是Set的子集。
与Set不同的是,WeakSet的键只能是Object或者继承自Object的类型。如果使用非对象作为键会报错TypeError
WeakSet的特点
和WeakMap有点类似,此处不写例子了。
- WeakSet的值不属于正式引用,不会阻止垃圾回收。
- 不可迭代值
WeakSet的使用场景
比起WeakMap,WeakSet的用处没有那么大。不过既然存在还是有应用场景的:
const disableElements = new WeakSet()
const loginButton = document.querySelector('#login')
disableElements.add(loginButton)
// 使用的时候通过查询元素是否在集合中,就可以知道它是否被禁用。而一旦元素从DOM树中删除,WeakMap也会释放其内存(为了严谨,假设没有其它地方引用这个对象)。
disableElements.has(loginButton) // true
复制代码
总结
Map和Set为管理数据提供了新的能力,而对应的Weak版本则简化了内存管理的工作。
历史篇:
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END