JavaScript中遍历Map对象键的最高效实现方式是什么
Map键遍历方案性能对比
前提定义
我们先有如下Map对象:
const map = new Map([['a', 'Apple'], ['b', 'Banana']])
需求是遍历该Map的所有键(即'a'、'b'),目前常见的遍历方案有以下4种:
遍历方案梳理
方案1:使用Map.prototype.forEach()
map.forEach((_value, key) => { console.log(key) })
- 优点:写法简单
- 缺点:需要忽略回调函数第一个入参,只能写
(_value, key) =>,不能直接用key =>的形式
方案2:将Map.prototype.keys()返回值转为数组后调用Array.prototype.forEach()
[...map.keys()].forEach(key => { console.log(key) })
- 优点:回调函数可直接使用
key =>形式 - 缺点:需要做
[...map.keys()]的转换,代码可读性稍差,额外产生数组创建的开销
方案3:使用for of循环遍历Map.prototype[Symbol.iterator]()
for (const [key] of map) console.log(key)
- 优点:速度较快,可读性好
- 缺点:没有使用箭头函数,部分开发者更偏好forEach的写法
方案4:使用for of循环遍历Map.prototype.keys()
for (const key of map.keys()) console.log(key)
该方案和方案3特性非常接近
性能最优结论
经过各大浏览器JS引擎的基准测试,四种方案的性能从高到低排序为:方案4 > 方案3 > 方案1 > 方案2
也就是说使用for of循环遍历Map.prototype.keys()的方案性能最优,原因如下:
- 方案2需要先把迭代器内容转换为完整数组,多了一次内存分配和全量遍历的开销,数据量越大性能下降越明显,是四种方案里最慢的。
- 方案1的
Map.forEach每次迭代都要触发回调函数调用,函数调用本身存在固定开销,性能弱于不需要额外回调的for of循环。 - 方案3需要对每次迭代返回的
[key, value]数组做解构操作,多了一层处理开销,性能略逊于直接拿到key迭代器的方案4。
如果是日常开发处理小体量Map,几种方案的性能差异几乎可以忽略,优先选择符合团队代码规范、可读性更好的写法即可;如果是处理超大规模的Map数据,再优先选用性能最优的方案4。
内容的提问来源于stack exchange,提问作者programmerRaj
相关产品推荐
相关产品推荐

