JS数组删除第一个和最后一个元素的方法

作者:闭包旅人

时间:2026-11-04

浏览:89

详细讲解JavaScript中删除数组第一个和最后一个元素的方法。涵盖pop、shift、splice、slice等核心方法的操作步骤、原地修改与不可变更新的区别、底层运行机制及场景选用建议。

文章目录
在 JavaScript 中,删除数组最后一个元素最直接的原生方法是 pop(),删除第一个元素则是 shift();若需在不改变原数组的前提下获得剔除首尾元素的新数组,则可以使用 slice() 或现代不可变方法 toSpliced()。本文将系统梳理这两种场景下的具体操作方法、运行机制及选用考量。
JS数组删除第一个和最后一个元素的方法
图 1:JavaScript 数组首尾元素删除操作全貌

一、删除最后一个元素(尾部删除)

删除数组末尾的元素在日常开发中十分普遍,例如撤销历史操作、栈结构的出栈等。根据是否允许修改原数组,有两种主流处理方式。

1. 原地修改:使用 array.pop()

pop() 是 JavaScript 数组内置的破坏性方法。它会直接移除数组的最后一项,减少数组的 length,并返回被移除的那项元素。若在空数组上执行,则返回 undefined。

const list = ['apple', 'banana', 'orange'];

// 删除末尾元素,并获取返回值
const removedItem = list.pop();

console.log(removedItem); // 示例输出: 'orange'
console.log(list);        // 示例输出: ['apple', 'banana']
console.log(list.length); // 示例输出: 2

除了 pop(),直接缩减数组的 length 属性(例如 list.length = list.length - 1)也可以达到截断末尾的效果,但这种方式无法返回被移除的值,且代码意图不如 pop() 清晰,因此通常推荐使用 pop()。

2. 不可变操作:使用 array.slice(0, -1)

在 React 状态管理或遵循纯函数原则的场景下,直接修改原数组会导致外部依赖产生不可预期的副作用。此时可以使用 slice() 创建一个不包含末尾项的新数组。

const original = ['apple', 'banana', 'orange'];

// slice(0, -1) 截取从索引 0 到倒数第一个元素(不含倒数第一个)
const updated = original.slice(0, -1);

console.log(updated);  // 示例输出: ['apple', 'banana']
console.log(original); // 示例输出: ['apple', 'banana', 'orange'] (原数组未改变)

如果运行环境支持 ECMAScript 2023(Node.js 20+ 或现代浏览器),还可以使用 original.toSpliced(-1, 1),它同样会返回一个剔除末尾项的新数组,原数组保持不变。

JS数组删除第一个和最后一个元素的方法
图 2:pop() 操作步骤及底层指针与返回值关系

二、删除第一个元素(头部删除)

删除数组开头的元素常用于队列的“出队”(FIFO)操作或按序处理待办任务。

1. 原地修改:使用 array.shift()

shift() 是最标准的头部删除方法。它会移除索引为 0 的元素,并把后续所有元素往前移动一个位置填充空缺,最后返回被删除的元素。

const queue = ['task-1', 'task-2', 'task-3'];

// 移出并获取队列首项
const currentTask = queue.shift();

console.log(currentTask); // 示例输出: 'task-1'
console.log(queue);       // 示例输出: ['task-2', 'task-3']

若对空数组调用 shift(),不会报错,而是安全地返回 undefined,数组长度依然为 0。

2. 不可变操作:使用 array.slice(1) 或数组解构

若希望得到剔除首项后的新数组而不破坏原始数组,slice(1) 是最简洁易读的写法:

const numbers = [10, 20, 30, 40];

// 截取索引 1 及之后的所有元素
const remaining = numbers.slice(1);

console.log(remaining); // 示例输出: [20, 30, 40]
console.log(numbers);   // 示例输出: [10, 20, 30, 40]

在解构赋值场景中,使用剩余参数语法也能实现类似效果:

const [first, ...rest] = numbers;
console.log(first); // 示例输出: 10 (第一个元素)
console.log(rest);  // 示例输出: [20, 30, 40] (其余元素组成的新数组)
JS数组删除第一个和最后一个元素的方法
图 3:shift() 移除首项后的内存索引平移过程

三、底层机制差异:为什么 shift 慢于 pop?

在理解了具体调用方法后,深入了解底层的执行开销对编写高质量代码很有帮助。pop() 与 shift() 虽然同样用于删除单个元素,但两者的性能复杂度存在显著差异:

  • pop() 的时间复杂度为 O(1): JavaScript 引擎维护着数组的连续存储空间与 length 属性。执行 pop() 时,引擎只需定位到末尾索引,释放该槽位的值,并将 length 减 1。原数组中其它任意元素的内存地址和索引均无需发生变动。
  • shift() 的时间复杂度为 O(n): 执行 shift() 时,由于索引 0 的位置被腾出,数组为了维持连续的下标访问特性,必须将索引 1 到 n-1 的所有元素依次向左搬移一位,并在搬移完成后更新 length。

在普通数十项至数百项的小数组中,这种时间差异在毫秒级内微乎其微;但在包含数十万项的大数组或高频循环调用的情境下,连续调用 shift() 会引起明显的性能瓶颈。如果业务场景需要高频从头部弹出数据,应考虑使用双端队列(Deque)结构或指针计数,避免反复触发全量数组移动。

JS数组删除第一个和最后一个元素的方法
图 4:原地修改与不可变更新的内存表现对比

四、避坑指南:必须注意的边界情况

1. 切忌使用 delete 关键字删除首尾元素

初学者容易尝试使用 delete array[0] 或 delete array[array.length - 1]。在 JavaScript 中,delete 操作符仅将对应属性的值置为空洞(empty / undefined),并不会改变数组的 length,这会导致数组变成“稀疏数组”(Sparse Array),破坏数组的内存紧凑性,甚至导致后续 forEach、map 等方法跳过该槽位产生意外行为。

注意提醒:绝对不要使用 delete array[i] 来删除数组元素。请务必使用 pop()、shift() 或 splice() 等正规数组方法。

2. 类数组对象(Arguments、NodeList)的处理

函数中的 arguments 对象或 DOM 查询返回的 NodeList 属于“类数组”,它们拥有 length 属性,但并未继承 Array.prototype 上的 pop() 与 shift() 方法。若直接调用会抛出 TypeError。

处理类数组前,应先使用 Array.from() 或展开语法将其转换为真实数组:

function handleElements() {
  // 转换为真实数组后再操作
  const args = Array.from(arguments);
  const first = args.shift();
  const last = args.pop();
  return { first, last, remaining: args };
}
JS数组删除第一个和最后一个元素的方法
图 5:首尾元素删除方法选择决策树

五、核心方法快速查阅表

根据操作位置、是否改变原数组以及返回值类型,可参照下表快速选定合适的方法:

目标位置 推荐方法 是否原地修改 返回值 时间复杂度 典型适用场景
最后一个元素 array.pop() 是(破坏性) 被删除的元素 O(1) 本地数据处理、栈操作、常规高性能删除
最后一个元素 array.slice(0, -1) 否(无副作用) 剔除尾部后的新数组 O(n) React / Redux 状态更新、不可变数据流
第一个元素 array.shift() 是(破坏性) 被删除的元素 O(n) 先进先出队列、简单消费型迭代
第一个元素 array.slice(1) 否(无副作用) 剔除头部后的新数组 O(n) 函数式处理、参数列表截取、状态更新
任意首尾 array.splice(start, 1) 是(破坏性) 包含被删元素的数组 O(n) 需要在删除的同时插入新元素或通用处理

总结而言,在追求性能和简单直观的脚本逻辑中,pop() 与 shift() 是最基础的内置工具;而在现代前端框架中,优先选用 slice() 或扩展语法创建新数组,能够有效保障组件状态的可预测性与可追溯性。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章