news 2026/6/20 2:58:22

【前端手撕】数组api

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【前端手撕】数组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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/20 2:55:59

Overlap:MIDPOINT(中值通道线)技术指标详解

Overlap&#xff1a;MIDPOINT&#xff08;中值通道线&#xff09;技术指标详解 一、MIDPOINT的定义 MIDPOINT&#xff08;Midpoint&#xff0c;中值通道线&#xff09; 是一种基础的趋势跟踪指标&#xff0c;在指定周期内&#xff0c;分别找出最高价的最高值和最低价的最低值&a…

作者头像 李华
网站建设 2026/6/20 2:54:41

突破脚本语言边界:ahk2_lib如何将AutoHotkey V2打造成Windows开发利器

突破脚本语言边界&#xff1a;ahk2_lib如何将AutoHotkey V2打造成Windows开发利器 【免费下载链接】ahk2_lib 项目地址: https://gitcode.com/gh_mirrors/ah/ahk2_lib 你是否曾为AutoHotkey脚本的性能瓶颈而烦恼&#xff1f;是否渴望在保持脚本语言简洁性的同时&#x…

作者头像 李华
网站建设 2026/6/20 2:51:47

MC68HC08中断机制与指令集实战解析:从原理到高效编程

1. 项目概述与核心价值 如果你正在捣鼓一块基于MC68HC08系列的老式微控制器板子&#xff0c;比如汽车ECU、工业控制器或者一些经典的嵌入式设备&#xff0c;那你肯定绕不开两个最核心的课题&#xff1a; 中断到底是怎么打断CPU正常工作的 &#xff0c;以及 那一大堆汇编指令…

作者头像 李华
网站建设 2026/6/20 2:45:12

深度学习模型训练与超参数调优:从“炼丹“到系统化方法论

深度学习模型训练与超参数调优&#xff1a;从"炼丹"到系统化方法论一、训练困境&#xff1a;当 Loss 曲线不再下降的那一刻 深度学习模型训练中最令人焦虑的时刻&#xff0c;不是代码报错&#xff0c;而是 Loss 曲线在某个平台期停滞不动。学习率调大则梯度爆炸&…

作者头像 李华
网站建设 2026/6/20 2:41:47

GanttProject 3步玩转项目管理:让复杂项目变简单的免费开源工具

GanttProject 3步玩转项目管理&#xff1a;让复杂项目变简单的免费开源工具 【免费下载链接】ganttproject Official GanttProject repository. 项目地址: https://gitcode.com/gh_mirrors/ga/ganttproject 还在为项目管理头疼吗&#xff1f;面对密密麻麻的任务、错综复…

作者头像 李华
网站建设 2026/6/20 2:29:58

5分钟掌握VideoSeal:开启视频水印技术的终极指南

5分钟掌握VideoSeal&#xff1a;开启视频水印技术的终极指南 【免费下载链接】videoseal Open and efficient video and image watermarking 项目地址: https://gitcode.com/gh_mirrors/vi/videoseal 在数字内容爆炸式增长的今天&#xff0c;视频版权保护已成为创作者和…

作者头像 李华