Skip to content

数组核心 API

数组方法速查表

方法行为特征返回值原数组影响
map遍历转换新数组❌ 不影响
filter条件过滤过滤后的新数组❌ 不影响
concat数组拼接新合并数组❌ 不影响
push/pop队尾操作操作后数组长度✅ 修改
unshift/shift队首操作操作后数组长度✅ 修改
sort排序/反转排序后的数组✅ 修改
slice区间截取新子数组❌ 不影响
splice删除/插入/替换被删元素数组✅ 修改
join数组转字符串连接后的字符串❌ 不影响
split字符串转数组切割后的新数组❌ 不影响
forEach遍历执行undefined❌ 不影响
some存在性验证boolean❌ 不影响
every全量验证boolean❌ 不影响
indexOf元素索引查找number(找不到返回-1)❌ 不影响
includes存在性检查boolean❌ 不影响
reduce累积计算最终累积值❌ 不影响

关键方法深度解析

slice vs splice

javascript
const arr = [1, 2, 3, 4, 5];

// slice 截取子数组(不修改原数组)
const subArr = arr.slice(1, 3); // [2,3]

// splice 删除/插入(修改原数组)
const removed = arr.splice(1, 2, 100, 200);
// 原数组变为 [1,100,200,4,5]
// removed 返回 [2,3]

join & split 转换技巧

javascript
// 数组转字符串
const str = ["a", "b", "c"].join("|"); // "a|b|c"

// 字符串转数组
const arr = str.split("|"); // ["a", "b", "c"]

空元素处理陷阱

javascript
// 创建包含空位的数组
const sparseArr = new Array(3); // [empty × 3]

// 遍历行为差异
sparseArr.map((_, i) => i); // [empty × 3](跳过空位)
Array.from(sparseArr).map((_, i) => i); // [0,1,2](填充undefined)

特殊场景处理

查找方法对比

javascript
const arr = [1, 2, NaN];

console.log(arr.indexOf(NaN)); // -1(无法识别NaN)
console.log(arr.includes(NaN)); // true(使用SameValueZero算法)

类数组对象处理

javascript
// 类数组特征示例
const arrayLike = {
  0: "a",
  1: "b",
  length: 2,
  // 手动添加数组方法
  push: Array.prototype.push,
};

// 转换方法
const realArray = Array.from(arrayLike); // ["a", "b"]

数组扁平化方案

javascript
// 1. flat方法(推荐)
[1, [2, [3]]].flat(Infinity); // [1,2,3]

// 2. 递归实现
function deepFlatten(arr, result = []) {
  arr.forEach((item) =>
    Array.isArray(item) ? deepFlatten(item, result) : result.push(item)
  );
  return result;
}

// 3. toString转换(仅限数字字符串)
const numStrArr = [1, [2, [3]]].toString().split(","); // ["1", "2", "3"]

底层实现原理

includes 方法实现

javascript
Array.prototype.includes = function (searchElement, fromIndex) {
  if (this == null) throw new TypeError();

  const arr = Object(this);
  const len = arr.length >>> 0;

  let start = fromIndex ? Number(fromIndex) : 0;
  if (isNaN(start)) start = 0;
  else if (start < 0) start = Math.max(len + start, 0);

  const isNaN = Number.isNaN(searchElement);
  for (let i = start; i < len; i++) {
    const current = arr[i];
    if (current === searchElement || (isNaN && Number.isNaN(current))) {
      return true;
    }
  }
  return false;
};

entries 迭代器实现

javascript
Array.prototype.entries = function () {
  let index = 0;
  const arr = this;

  return {
    next() {
      return index < arr.length
        ? { value: [index++, arr[index - 1]], done: false }
        : { done: true };
    },
    [Symbol.iterator]() {
      return this;
    },
  };
};

// 使用示例
for (const [idx, val] of [10, 20, 30].entries()) {
  console.log(idx, val); // 0 10 → 1 20 → 2 30
}

常见陷阱解析

自动分号插入问题

javascript
// 数组字面量换行导致的问题
let a = [1, 2, 3][2]; // 等价于 [1,2,3][2] → 返回3

// 对象字面量换行问题
let b = { x: 10 }["x"]; // 等价于 {x:10}["x"] → 返回10

数组长度异常场景

javascript
// 稀疏数组创建对比
const arr1 = [1]; // length:1
const arr2 = [1, ,]; // length:2(含空位)
const arr3 = new Array("10"); // length:1(元素为"10")
const arr4 = new Array(10); // length:10(全空位)

push 方法源码模拟

javascript
// 简化版push实现
function push(element) {
  this[this.length] = element;
  return this.length++;
}

// 使用示例
const obj = { 0: "a", length: 1 };
obj.push("b"); // obj变为 {0:'a', 1:'b', length:2}