数组 API 之 forEach、reduce
forEach 的实现
一个数组 arr 调用 forEach 方法,并传入 callback 方法:const arr = [1,2,3]
arr.forEach(function(value, index) {
console.log(value, index)
})
// 1 0
// 2 1
// 3 2
可以看到 callback 里面并没有传入 arr,那 callback 是怎么获取到数组 arr 的 value 和 index 的了。
它是通过 this 关键字来传入的。JavaScript 已经帮我们把 arr 传入了,类似调用了函数的 call 方法,并把 call 方法的第一个参数 this 指向 arr。如下:arr.forEach(function(){})
// 等同于
arr.forEach.call(arr, function(){})
我们的 forEach 的实现// 我们的 forEach 实现
obj.forEach = function(x) {
for (let i = 0; i < obj.length; i++) {
x(obj[i], i)
}
}
// 有个 obj
var obj = {
0: 1,
1: 2,
length: 2
}
// 调用 forEach 方法:
obj.forEach(function(value, key) {
console.log(value, key)
})
// 1 0
// 2 1
所以从数据结构来看,数组和对象其实没有差别。
arr.sort
arr.sort 原地排序自身,可以省空间。数组的其他 API 都不会修改原数组。
数组的 API 返回一个数组,所以可以操作成链式操作。
reduce
举个列子,范伟火车上打劫 “IC、IP、IQ 卡通通告诉我密码。” 😂,火车上有 10 个人。
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|
100 | 200 | 30 | 10 | 20 | 200 | 100 | 30 | 10 | 30 |
范伟手里最开始是么有钱的,钱数为 0,即初始值为 0
当打劫完第 1 个人,钱数变为了 0 + 100 = 100
打劫完第 2 个人,钱数变成了 100 + 200 = 300
打劫完第 3 个人,钱数就变成了 300 + 30 = 330
…
就是也就是累加。把之前打劫的钱加上新的打劫的钱。
const arr = [100, 200, 30, 10, 20, 200, 100, 30, 10, 30] |
map 和 filter 都可以用 reduce 表示。
map 用 reduce 表示
数组所有值乘以 2
const arr = [100, 200, 30, 10, 20, 200, 100, 30, 10, 30] |
filter 用 reduce 表示
比如过滤大于 100 的数值
const arr = [100, 200, 30, 10, 20, 200, 100, 30, 10, 30] |
所以说,map 和 filter 其实这是 reduce 的一个实现。