javascript数组怎么操作_有哪些常用方法

JavaScript数组方法分mutate(如push、splice)和immutable(如map、filter)两类,需据是否修改原数组及是否需新数组选择;误用易致React重渲染失败等bug。

怎么判断数组方法该用 mutate 还是 return new array

JavaScript 数组方法分两类:一类直接修改原数组(mutate),另一类返回新数组(immutable)。混淆这两类是 bug 高发区,比如在 React 中误用 push() 后没触发重渲染,或用 filter() 却忘了接返回值。

  • mutate 方法: push()pop()shift()unshift()splice()sort()reverse()
  • immutable 方法: map()filter()slice()concat()flat()toSorted()(ES2025)、with()(ES2025)
  • 注意 forEach() 不改变原数组,也不返回新数组(返回 undefined),别拿来赋值

splice() 怎么安全删/插/替 —— 参数顺序和返回值容易错

splice() 是唯一能同时删除、插入、替换的原地操作方法,但参数顺序反直觉:第一个是起始索引,第二个是删除个数,之后才是插入项。它还会返回被删元素组成的数组,不是原数组。

const arr = ['a', 'b', 'c', 'd'];
arr.splice(1, 2, 'x', 'y'); // 从索引1开始删2个 → ['b','c'],插入'x','y'
console.log(arr); // ['a', 'x', 'y', 'd']
console.log(spliceResult); // ['b', 'c'] ← 别漏了这个返回值
  • 只删不插:用 splice(start, deleteCount),如 arr.splice(-1, 1) 删末尾
  • 只插不删:用 splice(start, 0, ...items),第二个参数必须是 0
  • 想删完再用新数组?改用 toSpliced()(ES2025),它返回新数组,不改原数组

map()forEach() 什么时候不能互换

两者都遍历,但语义完全不同:map() 是“转换”,必须有返回值且生成新数组;forEach() 是“执行副作用”,比如发请求、改 DOM、累加变量,没有返回值(undefined)。

const nums = [1, 2, 3];
const doubled = nums.map(x => x * 2); // [2, 4, 6]
const ignored = nums.forEach(x => console.log(x * 2)); // 打印 2 4 6,ignored 是 undefined
  • map() 却没 return?结果数组全是 undefined
  • forEach() 想构造新数组?得手动 push(),不如直接用 map()
  • 需要提前退出循环?两个都不支持 break,改用 for...ofsome()/every()

扁平化嵌套数组 —— flat() 的深度和空位处理

flat() 默认只展开一层,遇到多层嵌套要传深度参数;它还会自动过滤掉空槽(empty),这点常被忽略。

const arr = [1, [2, [3, 4]], 5];
arr.flat();        // [1, 2, [3, 4], 5]
arr.flat(2);       // [1, 2, 3, 4, 5]
arr.flat(Infinity); // 同上,彻底展平
const sparse = [1, , 3]; // 空槽
sparse.flat();     // [1, 3] ← 空槽被移除了
  • 需要保留空槽?别用 flat(),改用 flatMap() + 显式返回或 reduce()
  • IE 不支持 flat()?用 reduce((acc, val) => acc.concat(Array.isArray(val) ? val : [val]), [])
  • 想按条件展平(比如只展平数组,跳过对象)?得手写递归或用 Lodash 的 flattenDeep()

有些方法看着像,行为却隔着一层语义墙;比如 sort() 默认按字符串排序,includes()SameValueZero 比较,findIndex() 找不到返回 -1 而不是 undefined —— 这些细节不翻 MDN 容易踩进静默陷阱。