当前位置: 首页 > news >正文

【前端手撕】数组api

碎碎念

校内任务告一段落!(暂时

map

map:映射—— 将原数组的每个元素映射成一个新值,组成新数组返回。

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指向的是arr

2. fn有三个参数是因为:

JavaScript 官方规定Array.prototype.map的回调函数必须接收这 3 个参数(按顺序):

  1. currentValue(当前元素的值) → 对应this[i]

  2. index(当前元素的索引) → 对应i

  3. array(调用 map 的原数组) → 对应this

后续调用的时候传参可以只传部分,但底层map仍然是塞了三个实参,只不过fn只接收部分,忽略了其他。

Tip

几乎所有数组方法的回调函数都是传这三个参数:

方法是否传 3 个参数备注
forEach✅ 是只遍历,不返回新数组
map✅ 是返回新数组
filter✅ 是返回新数组(筛选)
some/every✅ 是返回布尔值(测试是否通过)
find/findIndex✅ 是查找元素或索引
reduce特殊回调是(累加器, 当前值, 索引, 数组)4 个参数(因为多了一个累加器)

filter

filter()是 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),将数组中的每个元素依次进行归并操作,最终将整个数组坍缩(归约)为一个单一的结果值(可以是数字、对象或数组等)。

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

1. 边界问题处理

如果数组是空的,并且用户没有传初始值,按照这段代码: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

http://www.jsqmd.com/news/1046010/

相关文章:

  • 从“确定性答案”到“叠加态提问”:AI赋能下的探究式课堂范式研究(世毫九实验室原创研究)
  • 2026石家庄本地人必选防水补漏检测维修公司靠谱服务商TOP5推荐:房屋渗漏水检测维修/卫生间/厨房/天花板/阳台/外墙渗漏水检测补漏维修-暗管漏水检测专业仪器精准定位漏水点 - 即刻修防水
  • 2026年6月比较好的速冻库直销厂家有哪些,双温冷库/中型冷库/土建冷库/移动冷库/低温冷库/速冻库,速冻库厂家哪家靠谱 - 品牌推荐师
  • 碧蓝航线Live2D提取终极指南:从游戏资源到创意作品的完整转换
  • MicroStation 的进化之路:从图形终端到云端协同
  • 打通设计壁垒:实战LCEDA立创商城元件库向Cadence的高效迁移
  • Overlap:MIDPOINT(中值通道线)技术指标详解
  • 2026遵义2026正规漏水检测维修公司精选口碑榜TOP5权威推荐-精准定位检测漏水点-专业防水补漏堵漏维修、卫生间/厨房/屋顶/天沟/地下室/阳台防水漏水检测维修 - 安佳防水
  • 嵌入式串行通信实战:SPI与UART原理、配置与调试详解
  • MC68340串行模块深度解析:循环模式、多点模式与寄存器编程实战
  • 实践:利用EBI-ENA与Aspera在国内高效获取SRA数据
  • 【Springboot毕设全套源码+文档】基于Java+springboot“优兴趣”家教平台的设计与实现(丰富项目+远程调试+讲解+定制)
  • 深度解析Python开发者必备神器:Awesome-Python-CN中文资源大全的项目架构、核心内容体系与高效使用实战指南
  • Windows终端配置proxy - 老码识途
  • 2026赣州2026正规漏水检测维修公司精选口碑榜TOP5权威推荐-精准定位检测漏水点-专业防水补漏堵漏维修、卫生间/厨房/屋顶/天沟/地下室/阳台防水漏水检测维修 - 安佳防水
  • 2026连云港2026正规漏水检测维修公司精选口碑榜TOP5权威推荐-精准定位检测漏水点-专业防水补漏堵漏维修、卫生间/厨房/屋顶/天沟/地下室/阳台防水漏水检测维修 - 安佳防水
  • 多平台直播录制解决方案:从数据采集到内容管理的完整技术实现
  • 2026年萧山区青少年Python课程新趋势与杭州科迪姆科技培训有限公司实力解析 - 品牌鉴赏官2026
  • 从仿真到真实:构建高保真去模糊数据集的三种路径与实战指南
  • 2026年更新:河北无缝焊接窗制造商选择的核心维度与价值解析 - 品牌鉴赏官2026
  • ARM9微控制器架构解析:从AHB总线矩阵到外设驱动实战
  • java.lang.Throwable: [AGENT SERVICE]: MCP tools setup failed with index https://pyp
  • 2026年新发布上海可靠的企业反舞弊法律服务怎么选择?专家深度解析林东品律师 - 品牌鉴赏官2026
  • 2026秦皇岛漏水检测维修精选优质服务商TOP5推荐!卫生间漏水/厨房漏水/屋顶天花板漏水/阳台漏水/地下室漏水防水补漏检测维修-正规防水补漏公司优选口碑榜测评推荐 - 即刻修防水
  • 2026年当前迪庆角钢采购策略:一站式服务如何破解高原工程材料难题 - 品牌鉴赏官2026
  • 如何用思源宋体解决中文排版难题:5个实战技巧提升专业度
  • 2026年更新:贵阳中职教育选择指南,贵州工商职业大学的综合实力剖析 - 品牌鉴赏官2026
  • 2026遂宁2026正规漏水检测维修公司精选口碑榜TOP5权威推荐-精准定位检测漏水点-专业防水补漏堵漏维修、卫生间/厨房/屋顶/天沟/地下室/阳台防水漏水检测维修 - 安佳防水
  • Linux安装BIP高级版 - 老码识途
  • MPC555/556 TPU核心功能解析:DIO、SPWM、SIOP实战配置与硬件设计