有序和无序
- Object的key-value的排列是无序的,增删改查较快
- Array的index-value的排列必须是有序的,增删改查较慢
Map和Object的区别
- API不同,Map可以为任意类型的key(Object只能以字符串为key)
- Map是有序结构(最重要)
- Map的增删改查同样很快(跟Object差不多快,比有序的数组快很多)
Set和Array的区别
- API不同
- Set元素不能重复
- Set是无序结构,操作很快
WeakMap和WeakSet
- 弱引用,防止内存泄漏
- WeakMap只能用对象作为key,WeakSet只能用对象作为value
- 没有forEach方法和size属性,只能用add set get delete has方法
JS的垃圾清理机制是一种“标记清除”的机制,或者叫做“引用计数”。当一个变量,如果还被另一个 没有被清除的变量 引用时,它就不会被清除
先来举一个强引用的demo
const outerObj = {}
function fn() {
const innerObj = { name: 'shuangyue' }
outerObj.innerObj = innerObj
}
fn()
console.log(outerObj)
WeakMap的弱引用
const wMap = new WeakMap()
function fn() {
const innerObj = { name: 'shuangyue' }
wMap.set(innerObj, 'name info')
}
fn()
console.log(wMap)
wMap空空如也!
- 我们给wMap的key设置成某个对象后,这个对象该怎么销毁就怎么销毁,不会因为wMap引用了它,就一直存留着
- 弱引用:不影响对象的销毁过程。对象是可以被销毁的,但是基本数据类型(Number String Boolean)是不能被销毁的,所以只能用对象作为key
- 由于它的key随时会被销毁,很不稳定,因此不能用forEach去遍历或者用size去获取长度
- 防止内存泄漏:闭包会存在内存泄漏的问题,wMap的弱引用特性就会避免这个问题
- 垃圾清理的过程不一定是及时的,有时需要延时一段时间
WeakSet的用法也是类似的
const wSet = new WeakSet()
function fn() {
const obj = { name: 'Jobs' }
wSet.add(obj)
}
应用场景
建立一种关联关系,而且两者保持独立,不影响彼此的销毁逻辑
const wMap = new WeakMap()
const userInfo = { name: 'Alice' }
const cityInfo = { name: 'LosAngeles' }
wMap.set(userInfo, cityInfo)
wMap.get(userInfo)
如果直接写userInfo.city = cityInfo,那么销毁cityInfo对象的时候就会出问题