# 结合语义化、可读性和程序性能选择遍历方法 在实际开发中,经常会用到遍历方法对集合进行判断,过滤,筛选等. 对于ES5年代,我们大多依托基于lodash封装的`BI.each,BI.map,BI.some,BI.filter`方法,ES6时代,原生的`forEach,map,filter`等方法经常被使用 我们这里分析一下如何结合语义化、可读性和性能选择合适的遍历方法 ## BI.xxx和原生的遍历方法有什么区别? 1. BI.xxx方法保留了JQuery年代遍历方法的使用习惯,迭代调用的函数参数顺序为`(index,value)`,因此现在大多情况下,我们推荐使用原生遍历方法 2. BI.each方法可以遍历对象,原生javascript并未提供相应方法,`for...in`和`for..of`都无法同时获取key-value ## 语义化可读性的原则 1. 如果你需要将数组按照某种规则映射为另一个数组,就应该用map 2. 如果你需要进行简单的遍历,用forEach 3. 如果你需要提前中断迭代,那么使用some或every 4. 如果你需要过滤出符合条件的项,用filter 5. 如果你需要遍历数组累计计算出某个结果,那可以用reduce 6. 如果你需要先根据条件过滤,再按照规则映射为新数组,那就用filter加一个map 实际场景举例 ```javascript // 利用some提前中断的特性减少遍历 const arr = [1, 3, 4, 7]; const hasEven = arr.some(v => v % 2 === 0); const allOdd = arr.every(v => v % 2 === 1); ``` ```javascript // 迭代累计结果,两种实现并无高低之分,但求简单易懂 const arr = [1, 3, 4, 7]; const allCount1 = arr.reduce((previousValue, currentValue) => previousValue + currentValue, 0); let allCount2 = 0; arr.forEach(v => allCount2 += v); ``` ## 既要有性能意识,又无需过度追求性能 绝大多数情况,我们无需考虑究竟是`forEach`更快,还是`for...in`更快,我们的主要目标是写出清晰,稳定,可持续的代码. 与此同时,我们有尽量避免一些显而易见的代码缺陷,一个常见的误区是在遍历中重复进行额外的遍历. 对于在循环遍历中可以保持不变的信息,可以在遍历之外提前计算好再使用 ```javascript const arr1 = [ { name: "xiaoming", age: 17 }, { name: "dashan", age: 28 } ]; const arr2 = [14, 25, 36, 17]; // 每次都要进行map arr2.forEach(v => { if (arr1.map(j => j.age).includes(v)) { console.log(true); } }); // 对不变数据进行预先提取 const ages = arr1.map(j => j.age); arr2.forEach(v => { if (ages.includes(v)) { console.log(true); } }); ```