面试官往往会这么问:"JS 数组的常用方法有哪些?"然后追问:"哪些会改变原数组?哪些不会?"或"能举一个实际使用场景吗?"因此回答不仅要列出方法,还要讲清楚分类、返回值、是否改变原数组、典型用法与坑。
方法分类与速查
操作方法:增、删、改、查
排序方法:reverse、sort
转换方法:join
迭代方法:forEach、map、filter、some、every、find(包含 find、findIndex 等)
一、操作方法(增删改查)
增
- push():末尾追加,返回新长度;改原数组
- unshift():开头插入,返回新长度;改原数组
- splice(start, 0, ...items):指定位置插入,返回空数组;改原数组
- concat(...items):合并并返回新数组,不改原数组
js
let colors = ["red", "green"];
colors.push("blue"); // 3; colors => ["red","green","blue"]
colors.unshift("yellow"); // 4; colors => ["yellow","red","green","blue"]
colors.splice(1, 0, "purple"); // [] => 原数组被修改
let colors2 = colors.concat("black", ["white"]); // 新数组
删
- pop():末尾删除,返回被删项;改原数组
- shift():首项删除,返回被删项;改原数组
- splice(start, deleteCount):删除指定位置项,返回被删数组;改原数组
- slice(start, end):拷贝子数组,返回新数组;不改原数组
js
let colors = ["red", "green", "blue"];
let last = colors.pop(); // "blue"; colors => ["red","green"]
let first = colors.shift(); // "red"; colors => ["green"]
let removed = colors.splice(0, 1); // ["green"]; colors => []
let sub = colors.slice(1, 3); // 新数组,不改原数组
改
- splice(start, deleteCount, ...items):删除并插入,返回被删数组;改原数组
js
let colors = ["red", "green", "blue"];
colors.splice(1, 1, "purple"); // ["green"]; colors => ["red", "purple", "blue"]
查
- indexOf(item):返回索引,不存在返回 -1
- includes(item):返回 boolean
- find(callback):返回第一个满足条件的元素
- findIndex(callback):返回第一个满足条件的索引
js
let arr = [1, 2, 3, 4];
arr.indexOf(3); // 2
arr.includes(5); // false
let found = arr.find(x => x > 2); // 3
let foundIdx = arr.findIndex(x => x > 2); // 2
二、排序方法
reverse():反转数组,改原数组,返回引用 sort(compareFn):排序,改原数组,返回引用
js
let nums = [3, 1, 4, 1, 5];
nums.reverse(); // [5,1,4,1,3]; 改原数组
nums.sort((a,b)=>a-b); // [1,1,3,4,5]; 改原数组
注意:不传 compareFn 时,按 UTF-16 代码单元排序,对数字排序可能不符合预期,务必传比较函数。
三、转换方法
join(separator):用指定分隔符拼接成字符串,不改原数组
js
let colors = ["red", "green", "blue"];
colors.join(","); // "red,green,blue"
colors.join("||"); // "red||green||blue"
四、迭代方法(不改原数组)
- forEach(callback):遍历,无返回值
- map(callback):映射,返回新数组
- filter(callback):过滤,返回新数组
- some(callback):任一满足则 true
- every(callback):全部满足则 true
- find(callback):返回第一个满足元素
- findIndex(callback):返回第一个满足索引
- reduce/reduceRight:归约,常用于累加、组合
js
let nums = [1, 2, 3, 4];
let doubled = nums.map(x => x * 2); // [2,4,6,8]
let evens = nums.filter(x => x % 2 === 0); // [2,4]
let has = nums.some(x => x > 3); // true
let all = nums.every(x => x > 0); // true
let first = nums.find(x => x > 2); // 3
let sum = nums.reduce((a,b)=>a+b,0); // 10
五、是否改变原数组一览
改变原数组:push、pop、shift、unshift、splice、sort、reverse
不改变原数组:concat、slice、join、forEach、map、filter、some、every、find、findIndex、reduce、reduceRight、flatMap、flat、indexOf、includes
六、典型面试追问与场景举例
问:如何在不改变原数组的前提下在末尾追加一项?
答:使用 concat 或展开运算符 [...arr, item]。 问:如何移除数组中所有 falsy 值?
答:arr.filter(Boolean)。 问:如何按某属性排序对象数组?
答:arr.sort((a,b)=>a.key.localeCompare(b.key))。 问:forEach 与 map 的区别?
答:forEach 无返回值,仅遍历;map 返回新数组,常用于转换。 问:splice 与 slice 的区别?
答:splice 会改变原数组并支持插入/删除;slice 不会改变原数组,仅拷贝子集。
七、常见坑与避坑建议
- 直接用 sort() 对数字排序可能出错,务必传比较函数。
- splice 的参数易混淆,牢记参数顺序与返回值。
- 在需要保留原数组的场景,避免误用会改变原数组的方法。
- 注意 map 等迭代方法不会提前终止,如需提前中断请用 some/every 或传统 for。
八、总结
JS 数组方法多且常用,记住"是否改变原数组"是高频考点。建议按"操作、排序、转换、迭代"四个维度掌握,并多在实际项目中用这些方法替代手动循环,代码会更简洁、易读。
各位互联网搭子,要是这篇文章成功引起了你的注意,别犹豫,关注、点赞、评论、分享走一波,让我们把这份默契延续下去,一起在知识的海洋里乘风破浪!