【面试题】Map和Set
1. Map和Object的区别
- 形式不同
// Object
var obj = {key1: 'hello',key2: 100,key3: {x: 100}
}
// Map
var m = new Map([['key1', 'hello'],['key2', 100],['key3', {x: 100}]
])
- API不同
// Map的API
m.set('name', '小明') // 新增
m.delete('key2') // 删除
m.has('key3') // 判断是否有'key3'
m.forEach((value, key) => console.log(key, value)) // 使用forEach来循环遍历Map
m.size // 可以获取Map的长度
m.get('key1') // 获取键名为'key1'的值
- Object只能以字符串类型作为 key,但是Map能以任何类型最为 key
var a = {name: 'xxx'}
m.set(a, 'object key')
- Map是有序结构,Object是无序结构
Map虽然是有序结构,但是它的相关操作依然速度很快。下面举一个例子,分别在Map和Object中进行相同的操作,观察所花费的时间。
var obj = {}
for(let i = 0; i < 100 * 10000; i++){obj[i + ''] = i
}var m = new Map()
for(let i = 0; i < 100 * 10000; i++){m.set(i + '', i)
}// 查找操作花费时间对比
console.time('obj find')
obj['200000']
console.timeEnd('obj find')console.time('map find')
obj['200000']
console.timeEnd('map find')// 删除操作花费时间对比
console.time('obj delete')
delete obj['200000']
console.timeEnd('obj delete')console.time('map delete')
m.delete['200000']
console.timeEnd('map delete')
2. Set和Array的区别
- 形式不同
// Array
var arr = [10, 20, 30, 40]
// Set
var set = new Set([10, 20, 30, 40])
- API不同
// Set的API
set.add(50) // 增加
set.delete(10) // 删除
set.has(30) // 判断是否有 30
set.size // 获取Set的长度
set.forEach(val => console.log(val)) // 循环遍历
- Set元素不能重复(可以用于数组去重),数组元素可以重复
function unique(arr){const set = new Set(arr)return [...set]
}
- Set是无序结构,操作快;Array是有序结构,操作慢。下面举一个例子,分别在Set和Array中进行操作,观察所花费的时间。
var arr = []
for(let i = 0; i < 100 * 10000; i++){arr.push(i)
}var set = new Set()
for(let i = 0; i < 100 * 10000; i++){set.add(i)
}// Array添加元素花费的时间
console.time('arr unshift')
arr.unshift('a')
console.timeEnd('arr unshift')console.time('arr push')
arr.push('b')
console.timeEnd('arr push')// Set添加元素花费的时间
console.time('set add')
set.add('a')
console.timeEnd('set add')// 查找操作花费的时间
console.time('arr find')
arr.includes(500000)
console.timeEnd('arr find')console.time('set find')
set.has(500000)
console.timeEnd('set find')
3. WeakMap和WeakSet
- WeakMap 和 WeakSet 是弱引用,目的是防止内存泄漏
- WeakMap 只能使用对象作为 key,WeakSet 只能使用对象作为 value
- 因为WeakMap 和 WeakSet 是弱引用,里面的key随时可能会被销毁,所以不能使用 forEach 和 size,只能使用 add delete has。
// WeakMap
var wMap = new WeakMap()function fn(){const obj = {name: '小明'}wMap.set(obj, 'name info') // 弱引用
}fn()