1. 面试必备:JS数组方法全景解析
前端面试中,数组操作是必考的基础知识点。作为JavaScript最常用的数据结构之一,数组方法的熟练程度直接反映了开发者的编码功底。我在技术面试中经常发现,不少候选人对push/pop这类基础方法对答如流,但遇到reduce/complex场景就支支吾吾。本文将系统梳理JS数组的28个核心方法,按照增删改查、遍历转换、排序筛选三大类进行深度解析,每个方法都配有真实面试题示例和性能对比建议。
2. 基础增删改查方法
2.1 数组首尾操作四件套
javascript复制const fruits = ['apple', 'banana']
// 尾部添加(返回新长度)
fruits.push('orange') // ['apple', 'banana', 'orange']
// 尾部删除(返回被删元素)
fruits.pop() // 'orange'
// 头部添加(返回新长度)
fruits.unshift('strawberry') // ['strawberry', 'apple', 'banana']
// 头部删除(返回被删元素)
fruits.shift() // 'strawberry'
高频面试题:实现队列和栈应该用哪些数组方法组合?
- 队列(先进先出):push + shift
- 栈(后进先出):push + pop
2.2 万能splice方法
javascript复制const nums = [1, 2, 3, 4, 5]
// 删除:从索引1开始删2个元素
nums.splice(1, 2) // 返回[2,3],nums变为[1,4,5]
// 插入:从索引1插入'x','y'
nums.splice(1, 0, 'x', 'y') // nums变为[1,'x','y',4,5]
// 替换:索引2开始替换1个元素为'z'
nums.splice(2, 1, 'z') // 返回['y'], nums变为[1,'x','z',4,5]
避坑指南:splice会直接修改原数组,React状态更新时需要深拷贝后再操作
3. 遍历与转换方法
3.1 迭代三巨头对比
| 方法 | 返回值 | 中断遍历 | 应用场景 |
|---|---|---|---|
| forEach | undefined | 不可 | 单纯执行副作用 |
| map | 新数组 | 不可 | 数据转换 |
| filter | 过滤后数组 | 不可 | 条件筛选 |
javascript复制// 典型面试题:将对象数组转为属性数组
const users = [{id:1,name:'Alice'}, {id:2,name:'Bob'}]
const names = users.map(user => user.name) // ['Alice', 'Bob']
3.2 reduce高阶用法
javascript复制// 数组求和
[1, 2, 3].reduce((sum, num) => sum + num, 0) // 6
// 二维数组扁平化
[[1,2], [3,4]].reduce((flat, arr) => flat.concat(arr), []) // [1,2,3,4]
// 统计字符出现次数
'javascript'.split('').reduce((count, char) => {
count[char] = (count[char] || 0) + 1
return count
}, {})
性能提示:大数据集用for循环比reduce快3-5倍
4. 排序与筛选方法
4.1 sort的坑与技巧
javascript复制// 默认按字符串Unicode排序
[10, 2, 1].sort() // [1, 10, 2]
// 正确数字排序
[10, 2, 1].sort((a, b) => a - b) // [1, 2, 10]
// 对象数组排序
users.sort((a, b) => a.id - b.id)
常见错误:忘记sort会修改原数组,需要先.slice()复制
4.2 现代筛选方法
javascript复制const nums = [1, 2, 3, 4, 5]
// 找出第一个偶数
nums.find(num => num % 2 === 0) // 2
// 检查是否全为正数
nums.every(num => num > 0) // true
// 检查是否存在负数
nums.some(num => num < 0) // false
5. ES6+新增利器
5.1 扩展运算符妙用
javascript复制// 数组合并
const newArr = [...arr1, ...arr2]
// 数组去重
[...new Set([1,2,2,3])] // [1,2,3]
// 替代apply
Math.max(...[1,2,3]) // 3
5.2 Array.from的魔法
javascript复制// 类数组转换
Array.from(document.querySelectorAll('div'))
// 初始化序列
Array.from({length: 5}, (_, i) => i*2) // [0,2,4,6,8]
// 字符串转字符数组
Array.from('hello') // ['h','e','l','l','o']
6. 性能优化实战
6.1 方法选择黄金准则
- 需要结果数组:map/filter
- 只需遍历:forEach/for...of
- 提前终止:some/every/find
- 超大数组:for循环最快
6.2 内存优化技巧
javascript复制// 清空数组的三种方式对比
arr = [] // 新建空数组(推荐)
arr.length = 0 // 修改length属性
arr.splice(0) // 删除所有元素
7. 高频面试题库
- 实现数组去重(至少3种方式)
- 扁平化嵌套数组(考虑多层情况)
- 找出数组中出现次数最多的元素
- 不使用loop生成1-100的数组
- 两个有序数组合并并排序
我在技术评审中发现,90%的初级开发者对slice/splice的区别含糊不清。记住:slice是纯函数(不修改原数组),splice是破坏性操作。实际项目中推荐优先使用slice、concat等非破坏性方法,符合函数式编程原则。当面试官追问"为什么选择这个方法"时,能说出性能考量和副作用差异的候选人通常能获得加分。