现代 JavaScript 参考(4)

通过这三种方法,您可以避免在大多数情况下使用 for 和 forEach 。当你试图做一个 for 循环时,尝试用 map,filter 和 reduce 来组合试试。起初你可能很难做到这一点,因为它需要你学习一种新的思维方式,但一旦你得到它,事情会变得更容易。

愚人码头注:JavaScript 函数式编程建议看看以下几篇文章

简单的示例 const numbers = [0, 1, 2, 3, 4, 5, 6]; const doubledNumbers = numbers.map(n => n * 2); // [0, 2, 4, 6, 8, 10, 12] const evenNumbers = numbers.filter(n => n % 2 === 0); // [0, 2, 4, 6] const sum = numbers.reduce((prev, next) => prev + next, 0); // 21

通过组合 map,filter 和 reduce 来计算 10 分以上的学生成绩总和 sum :

const students = [ { name: "Nick", grade: 10 }, { name: "John", grade: 15 }, { name: "Julia", grade: 19 }, { name: "Nathalie", grade: 9 }, ]; const aboveTenSum = students .map(student => student.grade) // 我们将学生数组映射到他们成绩的数组中 .filter(grade => grade >= 10) // 我们过滤成绩数组以保持10分以上的元素 .reduce((prev, next) => prev + next, 0); // 我们将合计所有10分以上的成绩 console.log(aboveTenSum) // 44 -- 10 (Nick) + 15 (John) + 19 (Julia), 低于10的 Nathalie 被忽略 说明

让我们考虑一下下列数组:

const numbers = [0, 1, 2, 3, 4, 5, 6]; Array.prototype.map() const doubledNumbers = numbers.map(function(n) { return n * 2; }); console.log(doubledNumbers); // [0, 2, 4, 6, 8, 10, 12]

这里发生了什么?我们在 numbers 这个数组中使用 .map 方法,map 将会迭代数组的每个元素,并传递给我们的函数。该函数的目标是生成并返回一个新的值,以便 map 可以替换掉原本的数组。

我们来解释一下这个函数,使之更清楚一点:

const doubleN = function(n) { return n * 2; }; const doubledNumbers = numbers.map(doubleN); console.log(doubledNumbers); // [0, 2, 4, 6, 8, 10, 12]

numbers.map(doubleN) 将会产生 [doubleN(0), doubleN(1), doubleN(2), doubleN(3), doubleN(4), doubleN(5), doubleN(6)] 而它们分别等同于 [0, 2, 4, 6, 8, 10, 12]。

注意: 如果你不需要返回一个新的数组, 且只想执行一个带有副作用的循环,使用 for / forEach 循环会更为符合你的需求。

Array.prototype.filter() const evenNumbers = numbers.filter(function(n) { return n % 2 === 0; // 如果 "n" 符合条件返回 true , 如果 "n" 不符合条件则 false 。 }); console.log(evenNumbers); // [0, 2, 4, 6]

我们在 numbers 数组中使用 .filter 方法,过滤器遍历数组中的每个元素,并将其传递给我们的函数。函数的目标是返回一个布尔值,它将确定当前值是否被保留。过滤之后返回的数组将只包含保留值。

Array.prototype.reduce()

reduce 方法的目标是将迭代数组中的所有元素,减少 到只留下单一值。如何聚合这些元素取决于你。

const sum = numbers.reduce( function(acc, n) { return acc + n; }, 0 // 累加器迭代变量的初始值 ); console.log(sum) //21

就像 .map 和 .filter 方法一样, .reduce 方法被应用在数组上并接收一个函数做为第一个参数。

下面是一些差异:

.reduce 接受两个参数

第一个参数是一个函数,将在每个迭代步骤中被调用。

第二个参数是在第一个迭代步骤(读取下一个用的)的累加器变量的值(此处是 acc)。

函数参数

作为 .reduce 的第一个参数传递的函数需要两个参数。第一个(此处是 acc)是累加器变量,而第二个参数(n)则是当前元素。

累加器变量的值等于 上一次 迭代步骤中函数的返回值。在迭代过程的第一步,acc 等于你做为 .reduce 时第二个参数所传递的值(愚人码头注:也就是累加器初始值)。

进行第一次迭代

acc = 0 因为我们把 0 做为 reduce 的第二个参数

n = 0 number 数组的第一个元素

函数返回 acc + n –> 0 + 0 –> 0

进行第二次迭代

acc = 0 因为它是上次迭代所返回的值

n = 1 number 数组的第二个元素

函数返回 acc + n –> 0 + 1 –> 1

进行第三次迭代

acc = 1 因为它是上次迭代所返回的值

n = 2 number 数组的第三个元素

函数返回 acc + n –> 1 + 2 –> 3

进行第四次迭代

acc = 3 因为它是上次迭代所返回的值

n = 3 number 数组的第四个元素

函数返回 acc + n –> 3 + 3 –> 6

[…] 进行最后一次迭代

acc = 15 因为它是上次迭代所返回的值

n = 6 number 数组的最后一个元素

函数返回 acc + n –> 15 + 6 –> 21

因为它是最后一个迭代步骤了, .reduce 将返回 21 。

扩展阅读

展开操作符 “…”

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wywxjf.html