You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

2.5 KiB

结合语义化、可读性和程序性能选择遍历方法

在实际开发中,经常会用到遍历方法对集合进行判断,过滤,筛选等. 对于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...infor..of都无法同时获取key-value

语义化可读性的原则

  1. 如果你需要将数组按照某种规则映射为另一个数组,就应该用map
  2. 如果你需要进行简单的遍历,用forEach
  3. 如果你需要提前中断迭代,那么使用some或every
  4. 如果你需要过滤出符合条件的项,用filter
  5. 如果你需要遍历数组累计计算出某个结果,那可以用reduce
  6. 如果你需要先根据条件过滤,再按照规则映射为新数组,那就用filter加一个map

实际场景举例

//  利用some提前中断的特性减少遍历
const arr = [1, 3, 4, 7];

const hasEven = arr.some(v => v % 2 === 0);

const allOdd = arr.every(v => v % 2 === 1);
//  迭代累计结果,两种实现并无高低之分,但求简单易懂
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更快,我们的主要目标是写出清晰,稳定,可持续的代码.

与此同时,我们有尽量避免一些显而易见的代码缺陷,一个常见的误区是在遍历中重复进行额外的遍历. 对于在循环遍历中可以保持不变的信息,可以在遍历之外提前计算好再使用

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);
    }
});