🔥JavaScript 数组全解析:从「到底是不是数组?」到「方法全家桶」一篇搞定

"把数组玩透,才能把前端写活。"

本文首发于作者博客,持续更新,建议收藏。


目录

  1. 判断:我到底是不是数组?
  2. 静态方法:不需要实例就能用的工具箱
  3. 会改变原数组的方法(9 个)
  4. 不会改变原数组的方法(10+ 个)
  5. ES2023+ 的新玩具:toSorted / toReversed / toSpliced
  6. 高频手写题 & 易错点
  7. 一张思维导图带走全部记忆

1. 判断:到底是不是数组?

方式 代码 结果 说明
instanceof [] instanceof Array ✅ true 只能判断「由 Array 构造函数创建」的对象
Array.isArray Array.isArray([]) ✅ true 推荐!能识别 iframe / window 跨上下文
Object.prototype.toString Object.prototype.toString.call([]) [object Array] 通用,可区分 Array, Arguments, NodeList
constructor [].constructor === Array ✅ true 可伪造,不安全

结论:生产环境统一用 Array.isArray,面试题再补 toString 彰显深度。


2. 静态方法

方法 作用 示例
Array.from 类数组 / 可迭代 → 真数组 Array.from({length:3}, (_,i)=>i) // [0,1,2]
Array.of 避免 new Array(3) 的坑 Array.of(3) // [3]
Array.isArray 见第 1 节

3. 会改变原数组的方法(9 个)

口诀:「推(push) 波(pop) 前(shift) 后(unshift) 排(sort) 反(reverse) 切(splice) 填(fill) 拷(copyWithin)

方法 作用 返回 示例
push 尾部追加 新长度 arr.push(4)
pop 尾部删除 被删元素 arr.pop()
shift 头部删除 被删元素 arr.shift()
unshift 头部追加 新长度 arr.unshift(0)
splice 万能增删改 被删数组 arr.splice(1,2,'x','y')
sort 字典序排序 原数组 arr.sort((a,b)=>a-b)
reverse 反转 原数组 arr.reverse()
fill 填充 原数组 new Array(5).fill(0)
copyWithin 内部拷贝 原数组 [1,2,3,4].copyWithin(0,2)[3,4,3,4]

4. 不会改变原数组的方法

4.1 查询 & 过滤

  • includes (ES2016)
  • indexOf / lastIndexOf
  • find / findIndex / findLast(ES2022)
  • filter

4.2 转换

  • map
  • flat / flatMap (ES2019)

4.3 归约

  • reduce / reduceRight

4.4 遍历

  • forEach(注意:无法 break

4.5 切片

  • slice(start?, end?)

4.6 连接

  • concat

4.7 字符串化

  • join

5. ES2023+ 新玩具:非变异版本

新方法 语义 与原方法关系
toSorted 排序 返回新数组,同 slice().sort()
toReversed 反转 返回新数组
toSpliced 增删改 返回新数组
with(index, value) 替换单元素 函数式写法

有了它们,React 状态更新再也不用手动 ...arr 拷贝。


6. 高频手写题 & 易错点

6.1 手写 flat

js 复制代码
function flat(arr, depth = 1) {
  return depth > 0
    ? arr.reduce((acc, cur) => acc.concat(Array.isArray(cur) ? flat(cur, depth - 1) : cur), [])
    : arr.slice();
}

6.2 不要信任 sort 的稳定性

  • Chrome v8 在数组长度 ≤ 10 时插入排序,>10 时快排 → 老版本不稳定
  • 解决:arr.map((v,i)=>({v,i})).sort((a,b)=>a.v-b.v||a.i-b.i).map(o=>o.v)

6.3 稀疏数组的坑

js 复制代码
new Array(3).map(() => 1) // [empty × 3]  不会执行
[,,,].forEach(console.log) // 无输出

改用 Array.from({length:3}, () => 1)


7. 思维导图(文字版)

perl 复制代码
Array
├─ 判断
│  ├─ Array.isArray
│  └─ Object.prototype.toString
├─ 静态方法
│  ├─ Array.from
│  └─ Array.of
├─ 改变自身
│  ├─ push / pop / shift / unshift
│  ├─ splice / sort / reverse
│  └─ fill / copyWithin
├─ 不改变自身
│  ├─ 查询:includes find filter ...
│  ├─ 转换:map flat flatMap
│  ├─ 归约:reduce reduceRight
│  └─ 工具:slice join concat
└─ ES2023+
   ├─ toSorted / toReversed / toSpliced
   └─ with

结语

数组方法虽多,但记住「是否改变原数组」这条主线,再结合实际场景(React 状态不可变、算法题手写等),即可 掌握全部精髓。

相关推荐
excel1 小时前
Vue3 中的双向链表依赖管理详解与示例
前端
谢尔登1 小时前
【Nest】基本概念
javascript·node.js·express
前端小白从0开始1 小时前
Chrome DevTools高级用法:性能面板内存泄漏排查
前端·chrome·chrome devtools
EveryPossible2 小时前
带有渐变光晕
前端·javascript·css
jojo是只猫2 小时前
Vue 3 开发的 HLS 视频流播放组件+异常处理
前端·javascript·vue.js
卓码软件测评2 小时前
第三方软件登记测试机构:【软件登记测试机构HTML5测试技术】
前端·功能测试·测试工具·html·测试用例·html5
CS Beginner2 小时前
【html】canvas实现一个时钟
前端·html
林烈涛2 小时前
js判断变量是数组还是对象
开发语言·前端·javascript
Komorebi_99993 小时前
Unocss
开发语言·前端
来不及辣哎呀4 小时前
苍穹外卖项目面试总结话术
面试·职场和发展