javascript数组如何操作_有哪些常用的数组方法?

9次阅读

判断数组应使用Array.isArray()或Object.prototype.toString.call();push、pop、shift、unshift均修改原数组;map/Filter/find/some/every语义不同且不改原数组;slice只读,splice修改原数组。

javascript数组如何操作_有哪些常用的数组方法?

怎么判断一个变量是不是数组?别用 typeof

typeof [] 得到的是 "object",完全不可靠。真正安全的判断方式只有两个:Array.isArray()Object.prototype.toString.call()

  • Array.isArray([])true,这是 ES5+ 标准推荐方法,兼容性好(IE9+)
  • Object.prototype.toString.call([]) === '[object Array]' 适合需要支持极老环境(如 IE6–8)的场景
  • 避免用 instanceof Array:跨 iframe 时会失效,因为不同上下文的 Array 构造函数不相等

pushpopshiftunshift 这四个方法改不改变原数组?

全部都会直接修改原数组,返回值也各不相同——这点容易混淆,尤其 shiftunshift 的返回值不是新长度而是被移除/插入的元素本身。

const arr = [1, 2, 3]; arr.push(4);     // → 返回 4(新长度是 4),arr 变成 [1, 2, 3, 4] arr.pop();       // → 返回 4,arr 变成 [1, 2, 3] arr.shift();     // → 返回 1,arr 变成 [2, 3] arr.unshift(0);  // → 返回 3(新长度),arr 变成 [0, 2, 3]
  • 想“不改原数组”地加末尾元素?用扩展运算符[...arr, newItem]
  • 想删开头但保留原数组?用解构:const [, ...rest] = arr
  • pushunshift 性能较差(尤其大数组),因为要移动所有后续元素;pushunshift 快得多

mapfilterfindsomeevery 这些方法什么时候该用?

它们都不修改原数组,但语义和用途差异很大,选错会导致逻辑错误或性能浪费。

  • map:你要对每个元素做**转换**,且需要一个**等长新数组**(比如 arr.map(x => x * 2)
  • filter:你要**筛选子集**,返回满足条件的元素组成的数组(比如 arr.filter(x => x > 10)
  • find:你只要**第一个匹配项**,且不关心索引(返回值是元素本身,不是索引)
  • some:你只关心“有没有至少一个满足”,返回布尔值,遇到第一个 true 就停止遍历
  • every:你只关心“是否全部满足”,也是布尔值,遇到第一个 false 就停止

注意:findIndexindexOf 不同——前者接受函数,后者只支持严格相等;includesindexOf !== -1 的语义糖,但不支持回调。

立即学习Java免费学习笔记(深入)”;

spliceslice 容易搞混?关键看第三个参数

slice(start, end) 是纯读取,不改原数组;splice(start, deleteCount, ...items) 是写操作,会修改原数组并返回被删除的元素。

const arr = [1, 2, 3, 4, 5]; arr.slice(1, 3);    // → [2, 3],arr 不变 arr.splice(1, 2);   // → [2, 3],arr 变成 [1, 4, 5]
  • splice 第二个参数为 0 时,只插入不删除(类似 push/unshift 的通用版)
  • slice(0) 是浅拷贝数组的常用写法,比 arr.concat()[...arr] 更早被广泛使用
  • 想删掉某个值的所有出现?不能只靠 splice 一次调用,得配合循环filter

实际项目里最常被忽略的是:所有这些方法对稀疏数组(比如 [1, , 3])的行为不一致,mapfilter 会跳过空位,forEach 也会,但 for...in 会遍历索引属性,for...of 会把空位当作 undefined ——这种细节在处理用户上传的不规则数据时特别容易出 bug

text=ZqhQzanResources