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

0 阅读3分钟

“把数组玩透,才能把前端写活。”
本文首发于作者博客,持续更新,建议收藏。


目录

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

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

方式代码结果说明
instanceof[] instanceof Array✅ true只能判断「由 Array 构造函数创建」的对象
Array.isArrayArray.isArray([])✅ true推荐!能识别 iframe / window 跨上下文
Object.prototype.toStringObject.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

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 稀疏数组的坑

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

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


7. 思维导图(文字版)

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 状态不可变、算法题手写等),即可 掌握全部精髓。