JavaScript(下文简称JS)中最常用的数据结构有两种,即数组(下文用Array表示)和对象(下文用Object表示)。须要注意的是,本质上,数组也是一种对象,只不过是特殊的对象。遍历Array和Object中的元素,需要使用循环。在JS中,通常使用for循环语句来实现。那么,JS中的几种for循环写法的效率如何呢?本文做了一个简单的代码测试,仅供大家参考。注:该测试只是一个简单的测试,并不是十分严谨,相关的代码和结论仅供参考。
1. 语法说明
| for(let i = 0, len = arr.length; i++){ |
| console.log(arr[i]); |
| } |
| |
| for(let value in arr){ |
| console.log(value); |
| } |
| |
| |
| for(let key in obj){ |
| console.log(obj[key]); |
| } |
| |
| for(let value of arr){ |
| console.log(value); |
| } |
| |
| |
| for(let key of Object.keys(obj)){ |
| console.log(`${key}:\t`, obj[key]); |
| } |
| |
| |
| for(let value of Object.values(obj)){ |
| console.log(value); |
| } |
| |
| |
| for(let [key, value] of Object.entries(obj)){ |
| console.log(`${key}:\t`, obj[key]); |
| } |
| |
| arr.forEach((value, idx) => { |
| console.log(`${idx}:\t`, value); |
| }) |
| |
| |
| Object.keys(obj).forEach((key, idx) => { |
| console.log(`${idx}:\t${key}:\t`, value); |
| }) |
| |
| |
| Object.entries(obj).forEach((value, key) => { |
| console.log(`${key}:\t`, value); |
| }) |
2. 测试结论
- 先给出大多数场景下的使用建议(并不是性能最优,但其实也差不了太多),一般而言:
(1)对于数组(Array),如果不在循环体内使用break、continue语句时,则建议使用"forEach循环"语句,否则,使用“普通的for循环”语句;
(2)对于对象(Object),一般使用"for...in循环"语句即可。这与同时使用Object.keys() + 数组的“forEach”方法效果一致。
(3)对象(Object),可通过Object.entries()、Object.keys()和Object.values()方法, 转换为使用上边的数组(Array)的方式进行循环遍历。
|
用法 |
Array |
Object |
备注 |
for... |
for(let i = 0, len = arr.length; i++) |
最快 |
- |
普通的for循环,只能用于Array |
for...in |
for(let el in arr){...}, for(let key in obj) |
最慢 |
最快 |
for-in语句 |
for...of |
for() |
较慢 |
较快 |
for-of语句,对于Object需要使用Object.keys()、Object.values()或Object.entries()方法进行迭代 |
forEach... |
|
较快 |
最慢 |
forEach语句 |
3. 测试代码
| function doObjForLoop1(obj){ |
| let startTime = performance.now(); |
| for(let key in obj){ |
| |
| } |
| let endTime = performance.now(); |
| console.log((endTime - startTime) + "ms"); |
| } |
| |
| function doObjForLoop2(obj){ |
| let startTime = performance.now(); |
| for(let key of Object.keys(obj)){ |
| |
| } |
| let endTime = performance.now(); |
| console.log((endTime - startTime) + "ms"); |
| } |
| |
| function doObjForLoop3(obj){ |
| let startTime = performance.now(); |
| for(let [key, value] of Object.entries(obj)){ |
| |
| } |
| let endTime = performance.now(); |
| console.log((endTime - startTime) + "ms"); |
| } |
| |
| function doObjForLoop4(obj){ |
| let startTime = performance.now(); |
| Object.entries(obj).forEach((value, key) =>{ |
| |
| }) |
| let endTime = performance.now(); |
| console.log((endTime - startTime) + "ms"); |
| } |
| |
| |
| |
| |
| |
| function doArrForLoop1(arr){ |
| let startTime = performance.now(); |
| for(let i, len=arr.length; i < len; i++){ |
| |
| } |
| let endTime = performance.now(); |
| console.log((endTime - startTime) + "ms"); |
| } |
| |
| function doArrForLoop2(arr){ |
| let startTime = performance.now(); |
| for(let v of arr){ |
| |
| } |
| let endTime = performance.now(); |
| console.log((endTime - startTime) + "ms"); |
| } |
| |
| function doArrForLoop3(arr){ |
| let startTime = performance.now(); |
| arr.forEach((v, idx) => { |
| |
| }) |
| let endTime = performance.now(); |
| console.log((endTime - startTime) + "ms"); |
| } |
| |
| function doArrForLoop4(arr){ |
| let startTime = performance.now(); |
| for(let i in arr){ |
| |
| } |
| let endTime = performance.now(); |
| console.log((endTime - startTime) + "ms"); |
| } |
| |
| |
| |
| export function main(){ |
| let obj = {}; |
| let arr = [] |
| for(let i = 0; i < 1000000; i++){ |
| obj['k' + i] = {"a": i}; |
| arr.push(i); |
| } |
| |
| doObjForLoop1(obj); |
| doObjForLoop2(obj); |
| doObjForLoop3(obj); |
| doObjForLoop4(obj); |
| |
| console.log('------------------------'); |
| |
| doArrForLoop1(arr); |
| doArrForLoop2(arr); |
| doArrForLoop3(arr); |
| doArrForLoop4(arr); |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通