import Playground from ’../../../components/Playground.tsx’
在写 React 的时候,用的最多的就是 map 方法。这很经典,就不再记录了。
数组方法速查表h3
| 维度 | 方法列表 | 核心提醒 |
|---|---|---|
| 修改原数组 | push/pop/shift/unshift/splice/sort/reverse/fill | 慎用!需保留原数组则先拷贝([…arr]) |
| 返回新数组 | slice/map/filter/concat/flat | 原数组不变,可链式调用(如arr.filter().map()) |
| 无返回值 | forEach | 仅遍历,不能链式调用 |
| 返回单个值 | find/findIndex/every/some/indexOf/includes/reduce | 按需选择(找元素用 find,找索引用 findIndex,累加用 reduce) |
对数组的操作,有影响原数组的,也有不影响原数组的。
会修改原数组的方法h3
这类方法直接改变原数组,是新手最容易出错的点,记录时重点标注 “修改原数组”:
| 方法 | 功能 | 易错点 |
|---|---|---|
push() | 向数组末尾添加元素 | 返回值是新数组长度,不是新数组 |
pop() | 删除数组最后一个元素 | 返回值是被删除的元素,不是剩余数组 |
shift() | 删除数组第一个元素 | 返回值是被删除的元素,且性能比 pop() 差(数组会重新索引) |
unshift() | 向数组开头添加元素 | 返回值是新数组长度,且性能差(数组重新索引) |
splice(start, deleteCount, ...items) | 增 / 删 / 改数组元素 | ① start 为负数时从末尾计数;② 返回值是被删除的元素数组;③ 第二个参数是 “删除数量” 不是 “结束索引” |
sort((a,b) => {}) | 数组排序 | ① 默认按字符串 Unicode 排序(数字需自定义比较函数);② 比较函数返回 a-b 升序,b-a 降序 |
reverse() | 反转数组 | 无参数,直接反转原数组,返回反转后的数组(和原数组指向同一内存) |
fill(value, start, end) | 填充数组 | start/end 可选,左闭右开,填充覆盖原数组元素 |
splice 用法h4
语法:array.splice(start, deleteCount, item1, item2, ...)
start:开始的位置下标deleteCount:删除的数量item1, item2, ...:要添加的元素
<Playground client
// 场景 1:单纯插入(在 Bob 和 Charlie 之,间插入 Eve) const removed1 = team.splice(2, 0, ‘Eve’) console.log(‘team:’, team) // [‘Alice’, ‘Bob’, ‘Eve’, ‘Charlie’, ‘Diana’] console.log(‘removed1:’, removed1) // [] (没有删除任何元素)
// 场景 2:单纯删除(删除最后一个成员 Diana) // -1 表示从倒数第一个元素开始,删除 1 个 const removed2 = team.splice(-1, 1) console.log(‘team:’, team) // [‘Alice’, ‘Bob’, ‘Eve’, ‘Charlie’] console.log(‘removed2:’, removed2) // [‘Diana’]
// 场景 3:替换(将 Bob 替换为 Frank 和 Grace) const removed3 = team.splice(1, 1, ‘Frank’, ‘Grace’) console.log(‘team:’, team) // [‘Alice’, ‘Frank’, ‘Grace’, ‘Eve’, ‘Charlie’] console.log(‘removed3:’, removed3) // [‘Bob’] (Bob 被替换出去了) `} />
① start为负数时从末尾计数; ② 返回值是被删除的元素数组; ③ 第二个参数是 “删除数量” 不是 “结束索引”
fill 用法h4
语法:array.fill(value, start, end)
value:要填充的值start:开始的位置下标end:结束的位置下标
<Playground client
// 它的意思是:用 0 填充从索引 1 开始,到索引 3 之前的位置 arr.fill(0, 1, 3)
console.log(arr) // [1, 0, 0, 4, 5] `} />
start/end可选,左闭右开,填充覆盖原数组元素
不会修改原数组的方法h3
这类方法返回新结果,原数组不变,易和 “修改原数组” 的方法混淆:
| 方法 | 功能 | 易错点 |
|---|---|---|
slice(start, end) | 截取数组片段 | ① 左闭右开;② start/end 为负数从末尾计数;③ 返回新数组,原数组不变 |
map((item) => {}) | 遍历并返回新数组 | ① 必须有返回值,否则新数组全为 undefined;② 不会过滤元素(长度与原数组一致) |
filter((item) => {}) | 过滤并返回新数组 | 返回值为 true 的元素保留,新数组长度可能小于原数组 |
concat(arr1, arr2) | 拼接数组 | ① 可拼接多个数组或值;② 返回新数组,原数组不变(ES6 推荐使用 [...arr1, ...arr2]) |
flat(depth) | 扁平化数组 | ① depth 默认 1,Infinity 可展平任意深度;② 返回新数组,原数组不变 |
遍历与归并方法h3
无返回值 / 返回特定值,这类方法重点在 “遍历逻辑”,返回值易混淆:
| 方法 | 功能 | 易错点 |
|---|---|---|
forEach((item) => {}) | 遍历数组 | ① 无返回值(默认 undefined);② 无法用 break/continue 中断遍历 |
find((item) => {}) | 找第一个符合条件的元素 | ① 返回找到的元素,无则 undefined;② 找到后立即停止遍历 |
findIndex((item) => {}) | 找第一个符合条件的索引 | ① 返回索引,无则 -1;② 注意和 indexOf 的区别(indexOf 找值,findIndex 找条件) |
every((item) => {}) | 判断所有元素是否符合条件 | ① 全满足返回 true,否则 false;② 有一个不满足立即停止遍历 |
some((item) => {}) | 判断是否有元素符合条件 | ① 有一个满足返回 true,否则 false;② 找到后立即停止遍历 |
reduce((acc, cur) => {}, init) | 累加 / 归并数组 | ① acc 是累计值,cur 是当前元素;② 无初始值时,acc 默认第一个元素,cur 从第二个开始(易出错) |
reduce 用法h4
语法:array.reduce(callback(accumulator, currentValue, currentIndex, array), initialValue)
callback:回调函数,接收四个参数:accumulator:累计值currentValue:当前元素currentIndex:当前索引array:原数组
initialValue:初始值(可选)
<Playground
clientconst arr = [1,2,3]; // 有初始值(推荐):acc从0开始,cur依次为1、2、3 const sum1 = arr.reduce((acc, cur) => acc + cur, 0); // 6 console.log(sum1) // 无初始值:acc=1,cur=2 → acc=3,cur=3 → 最终6(空数组会报错) const sum2 = arr.reduce((acc, cur) => acc + cur); // 6 console.log(sum2) // 空数组无初始值会报错 const emptySum = [].reduce((acc, cur) => acc + cur); // TypeError}
/>
查找与判断方法h3
| 方法 | 功能 | 易错点 |
|---|---|---|
indexOf(value, start) | 找元素首次出现的索引 | ① 返回索引,无则-1;② 无法查找NaN([NaN].indexOf(NaN) → -1) |
includes(value, start) | 判断数组是否包含元素 | ① 返回布尔值;② 能识别NaN([NaN].includes(NaN) → true) |
lastIndexOf(value) | 找元素最后出现的索引 | ① 从后往前找,返回索引,无则-1;② 无法查找NaN([NaN].indexOf(NaN) → -1) |
评论