碎碎念
校内任务告一段落!(暂时
map
map**:映射** ------ 将原数组的每个元素映射成一个新值,组成新数组返回。
javascript
Array.prototype.map = function(fn) {
const res = []
for (let i = 0; i < this.length; i++) {
res.push(fn(this[i], i,this))
}
return res
}
-
使用map是arr.map这样用,所以this指向的是arr
-
fn有三个参数是因为:
JavaScript 官方规定 Array.prototype.map 的回调函数必须接收这 3 个参数(按顺序):
-
currentValue(当前元素的值) → 对应this[i] -
index(当前元素的索引) → 对应i -
array(调用 map 的原数组) → 对应this
后续调用的时候传参可以只传部分,但底层map仍然是塞了三个实参,只不过fn只接收部分,忽略了其他。
Tip
几乎所有数组方法的回调函数都是传这三个参数:
| 方法 | 是否传 3 个参数 | 备注 |
|---|---|---|
forEach |
✅ 是 | 只遍历,不返回新数组 |
map |
✅ 是 | 返回新数组 |
filter |
✅ 是 | 返回新数组(筛选) |
some / every |
✅ 是 | 返回布尔值(测试是否通过) |
find / findIndex |
✅ 是 | 查找元素或索引 |
reduce |
❌ 特殊 | 回调是 (累加器, 当前值, 索引, 数组),4 个参数(因为多了一个累加器) |
filter
filter() 是 JavaScript 数组原型上的一个内置方法。它的核心功能是根据指定条件(回调函数) ,从原数组中筛选出符合要求的元素,并组成一个新数组返回。即不破坏原数组。
javascript
Array.prototype.filter = function(fn) {
const res = []
for (let i = 0; i < this.length; i++) {
// 如果fn返回true(即满足条件),则把当前元素加到res数组中
if (fn(this[i], i, this)) {
res.push(this[i])
}
}
return res
}
reduce
reduce 方法通过维护一个持续传递的累加器 (即上一次回调的返回值 res),将数组中的每个元素依次进行归并操作,最终将整个数组坍缩(归约) 为一个单一的结果值(可以是数字、对象或数组等)。
javascript
Array.prototype.reduce = function(fn, initValue) {
let res, start = 0
if (arguments.length !== 1) {
// 传了两个参数,有初始值
res = initValue
} else {
// 只传了一个参数,从第一个元素开始
res = this[0]
start = 1
}
for (let i = start; i < this.length; i++) {
// fn 执行完后返回一个新值,覆盖掉 res,继续下一次循环。
res = fn(res, this[i], i, this)
}
return res
}
Tip
- 边界问题处理
如果数组是空的,并且用户没有传初始值, 按照这段代码:res = this[0] 会变成 undefined,start = 1,循环不执行,最后返回 undefined。但真实的 JS 引擎在这种情况下会直接报错(TypeError: Reduce of empty array with no initial value)。因此可以在开头加一句:
javascript
if (this.length === 0 && arguments.length === 1) {
throw new TypeError('Reduce of empty array with no initial value');
}
- 为什么用
arguments.length来判断是否有初始值,而不是直接用if (initValue === undefined)?
因为undefined是合法的初始值。例如:
javascript
[1, 2].reduce(fn, undefined);
-
如果用
initValue === undefined判断,会误以为没传初始值,导致程序逻辑错乱。 -
如果用
arguments.length === 2判断,就能精准识别:"用户确实传了第二个参数 (只是值恰好是undefined)",从而正确地把res设为undefined。