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