讲解

数组是有序的数据列表,用方括号创建:const list = [1, 2, 3]。数组可以装任意类型的值,甚至混合类型(虽然实践中建议同类型)。通过下标访问元素,下标从 0 开始,list[0] 是第一个元素;length 属性给出元素个数,最后一个元素的下标是 length - 1,也可以用 list.at(-1) 直接取倒数第一个。

数组首尾两端的增删有四个方法:push 在末尾追加、pop 从末尾删除并返回、unshift 在开头插入、shift 从开头删除并返回。其中 push/pop 是 O(1) 快操作,unshift/shift 要移动所有元素,大数组上较慢。中间位置的操作用 splice(可删可插可替换,会修改原数组)和 slice(截取副本,不改原数组)——这对「一个改原数组、一个返回新数组」的组合是数组方法里最需要记牢的一对。

数组是对象,按引用传递和比较:把数组赋值给另一个变量只是复制了引用,两边改的是同一份数据。判断一个值是不是数组用 Array.isArray()。创建数组除了字面量,还有 Array.of(1, 2, 3)、Array(3).fill(0)(长度为 3、全填 0)、Array.from({ length: 5 }, (_, i) => i)(生成 [0,1,2,3,4],非常实用)。

示例

const nums = [10, 20, 30];
console.log('第一个:', nums[0], '最后一个:', nums.at(-1), '长度:', nums.length);

// 首尾增删
nums.push(40);
console.log('push 后:', nums);
const removed = nums.pop();
console.log('pop 弹出:', removed, '剩余:', nums);

// slice 不改原数组,splice 改原数组
const letters = ['a', 'b', 'c', 'd', 'e'];
console.log('slice 截取:', letters.slice(1, 3), '原数组:', letters);
letters.splice(1, 2); // 从下标 1 删 2 个
console.log('splice 后:', letters);

// 引用语义
const a = [1, 2];
const b = a;
b.push(3);
console.log('a 也变了:', a, '—— b 和 a 是同一个数组');

// 快速创建
console.log(Array(3).fill(0));
console.log(Array.from({ length: 5 }, (_, i) => i * i));

console.log('包含判断:', nums.includes(20), '位置:', nums.indexOf(20));

常见坑

  • 混淆 slice 与 splice:slice 截取副本(原数组不变),splice 就地修改(返回被删元素)。拼写只差一个字母,行为天差地别。
  • 直接给 length 赋值:arr.length = 2 会真的把数组截断成 2 个元素,数据丢失不可逆。这偶尔被当作清空技巧(length = 0),但易误伤。
  • 用 delete 删数组元素:delete arr[1] 留下一个空洞(empty 槽位),length 不变,遍历行为怪异。删元素用 splice 或 filter。
  • 稀疏数组:[1, , 3] 中间的空槽和显式的 undefined 不是一回事,map 等方法会跳过空槽。避免制造稀疏数组。

小结

数组按下标存取,push/pop/shift/unshift 管两端,slice 不动原数组、splice 动。数组按引用传递。下一节学习数组最强大的部分:map、filter、reduce 等方法。