JavaScript方法帮你精通JS:神奇的array.reduce方法的10个案例

  JavaScript是当今流行语言中对函数式编程支持最好的编程语言。我们继续构建函数式编程的基础,在前文中分解介绍了帮助我们组织思维的四种方法js foreach遍历对象,分别为:

  - array.reduce方法 帮你精通JS:神奇的array.reduce方法的10个案例

  - array.map方法 帮你精通JS:神奇的array.map的6个案例

  - array.flat方法,以及array.flatMap 帮你精通JS: array.flat与flatMap用法指南

  以上四种方法的共同点都是对array作转换和变形,而且都不需要陷入到琐碎loop实现细节的 dirty details之中。

  接下来,我们将学习更加通用的函数式迭代方法 array.forEach()。

  一句话概括区分 forEach 与 map 的区别,pure-function 就用 map,impure-function 则用 forEach。

  array.forEach() 语法概述

  forEach() 方法对数组的每个元素执行一次给定的函数。

   const array1 = ['a', 'b', 'c'];

    array1.forEach(element => console.log(element));
    // expected output: "a"
    // expected output: "b"

  参数

  callback

  为数组中每个元素执行的函数,该函数接收一至三个参数:

  - currentValue 数组中正在处理的当前元素。

  - index 可选 数组中正在处理的当前元素的索引。

  - array 可选 forEach() 方法正在操作的数组。

  thisArg 可选 可选参数。当执行回调函数 callback 时,用作 this 的值。

  返回值

  undefined。

  array.forEach() 描述

  forEach() 方法按升序为数组中含有效值的每一项执行一次 callback 函数,那些已删除或者未初始化的项将被跳过(例如在稀疏数组上)。

  可依次向 callback 函数传入三个参数:

  数组当前项的值数组当前项的索引数组对象本身

  如果 thisArg 参数有值,则每次 callback 函数被调用时,this 都会指向 thisArg 参数。如果省略了 thisArg 参数,或者其值为 null 或 undefined,this 则指向全局对象。按照函数观察到 this 的常用规则,callback 函数最终可观察到 this 值。

  forEach() 遍历的范围在第一次调用 callback 前就会确定。调用 forEach 后添加到数组中的项不会被 callback 访问到。如果已经存在的值被改变,则传递给 callback 的值是 forEach() 遍历到他们那一刻的值。已删除的项不会被遍历到。如果已访问的元素在迭代时被删除了(例如使用 shift()),之后的元素将被跳过——参见下面的示例。

  forEach() 为每个数组元素执行一次 callback 函数;与 map() 或者 reduce() 不同的是,它总是返回 undefined 值,并且不可链式调用。其典型用例是在一个调用链的最后执行副作用(side effects,函数式编程上,指函数进行 返回结果值 以外的操作)。

  forEach() 被调用时,不会改变原数组,也就是调用它的数组(尽管 callback 函数在被调用时可能会改变原数组)。(此处说法可能不够明确,具体可参考EMCA语言规范:'forEach does not directly mutate the object on which it is called but the object may be mutated by the calls to callback function.',即 forEach 不会直接改变调用它的对象,但是那个对象可能会被 callback 函数改变。)

  注意: 除了抛出异常以外,没有办法中止或跳出 forEach() 循环。如果你需要中止或跳出循环,forEach() 方法不是应当使用的工具。

  若你需要提前终止循环,你可以使用:

  这些数组方法则可以对数组元素判断,以便确定是否需要继续遍历:

  只要条件允许,也可以使用 filter() 提前过滤出需要遍历的部分,再用 forEach() 处理。

  案例 01 不对未初始化的值进行任何操作(稀疏数组)

  如你所见,3 和 7 之间空缺的数组单元未被 forEach() 调用 callback 函数js foreach遍历对象,或进行任何其他操作。

   const arraySparse = [1,3,,7];

    let numCallbackRuns = 0;
    arraySparse.forEach(function(element){
      console.log(element);
      numCallbackRuns++;
    });
    console.log("numCallbackRuns: ", numCallbackRuns);
    // 1
    // 3
    // 7

  案例 02 将 for 循环转换为 forEach

   const items = ['item1', 'item2', 'item3'];

    const copy = [];
    // before
    for (let i=0; i {
        if (Array.isArray(i))
          result.push(...flatten(i));
        else
          result.push(i);
      })
      return result;
    }
    // Usage
    const problem = [1, 2, 3, [4, 5, [6, 7], 8, 9]];
    flatten(problem); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

  案例08 针对 promise 或 async 函数的使用备注

  如果使用 promise 或 async 函数作为 forEach() 等类似方法的 callback 参数,最好对造成的执行顺序影响多加考虑,否则容易出现错误。

   let ratings = [5, 4, 5];

    let sum = 0;
    let sumFunction = async function (a, b) {
        return a + b;
    }
    ratings.forEach(async function(rating) {
        sum = await sumFunction(sum, rating);
    })
    console.log(sum);
    // Expected output: 14
    // Actual output: 0
文章由官网发布,如若转载,请注明出处:https://www.veimoz.com/1299
0 评论
713

发表评论

!