为什么 push 和 pop 感觉自然,而 shift 不会

发布: (2025年12月29日 GMT+8 08:41)
7 min read
原文: Dev.to

I’m happy to help translate the article, but I need the full text you’d like me to translate. Could you please paste the content (or the portion you want translated) here? I’ll keep the source link unchanged and preserve all formatting as you requested.

JavaScript 数组悄悄优化的地方

当我第一次开始使用 JavaScript 数组时,pushpop 立刻让人感觉直观。
你向末尾添加元素。
你从末尾移除元素。
没有任何令人惊讶的事发生。

随后我开始使用 shift
它正如承诺的那样——移除第一个元素——但总是感觉更沉重、更慢,有一种难以言喻的不舒服感。

起初,我以为这种感觉只是直觉,没有实质依据。
事实并非如此。

数组看起来很简单,直到你修改前端

大多数人对数组都有一个非常简单的心智模型:一个整齐的项目列表,按顺序排列,随时可以在需要的地方进行修改。这个模型大体上是可行的,直到你开始修改数组的前端。

这时一个重要细节就显现出来了:

JavaScript 数组针对末端进行了优化,而不是针对开头。

一旦你理解了这一点,pushpopshift 之间的区别就不再显得任意。

为什么 push 看起来毫不费力

当你调用 push 时,引擎已经知道下一个元素应该放在哪里。

  • 有明确的结束位置。
  • 长度是已知的。
  • 不需要移动其他元素。

值被添加,长度被更新,执行继续。从运行时的角度来看,这是一种协作操作。它是配合数组的结构而不是对抗它。这就是为什么即使数组增长,push 仍然显得廉价且可预测。

为什么 pop 同样自然

pop 只是相反的操作。

  • 删除最后一个元素。
  • 长度减小。
  • 不需要重新组织。

同样,数组中没有其他内容需要改变。pushpop 都在结构的边界上操作,尽可能少地触及数据,这种效率也体现在使用时的感觉上。

为什么 shift 感觉不同

shift 删除第一个元素。表面上听起来同样简单,但实际上并非如此。

删除索引为 0 的元素意味着其余所有元素都必须移动。每个剩余的项都必须重新分配一个新的索引:

  • 原本在 1 位置的变为 0
  • 原本在 2 位置的变为 1
  • 依此类推。

数组必须重新索引。这不是怪癖;它是数组工作方式以及索引访问保持方式的直接结果。一旦你意识到这一点,围绕 shift 的不适感就能解释得通——它要求引擎做显著更多的工作。

在你能命名之前,你就能感受到成本

你不需要正式的性能术语就能注意到这种差异。你会在以下情况下感受到它:

  • 当数组变得更大时
  • 当操作重复发生时
  • 当响应性开始变得重要时

在末尾的操作悄然扩展。在开头的操作大声扩展。这是一种理解源于经验而非词汇的情形。后来,当性能概念以更正式的方式被引入时,它们会显得熟悉,因为这种行为已经被观察到。

数组是结构化对象,而非抽象列表

另一个有帮助的思维转变是记住,JavaScript 数组并不是抽象的容器。它们是具有数值键和长度约定的结构化对象。每个索引都是一个属性。更改数组的前端意味着一次性更改多个属性。

从这个角度看,shift 不再是 pop 的兄弟。它是一种根本不同的操作,具有截然不同的含义。

shift 仍然是正确选择时

这些并不意味着 shift 错误;而是说明它应该被有意使用。何时使用 shift

  • 数组很小
  • 操作不频繁
  • 可读性比纯粹的效率更重要

此时 shift 完全可以接受。理解成本并不是要避免某些方法,而是要有意识地而非偶然地选择它们。

这里的真正教训

最重要的收获并不是关于某个具体的数组方法,而是学会提出更好的问题。

  • 不是:“这能工作吗?”
  • 而是:“这会迫使运行时做什么?”

这个问题的适用范围远超数组。它同样出现在:

  • 字符串操作
  • 对象拷贝
  • 状态更新
  • 只在负载下才出现的性能问题

一旦你开始这样提问,JavaScript 就不再显得不可预测,而是变得可以解释。

pushpop 感觉自然,是因为它们符合 JavaScript 数组的设计方式。shift 则显得别扭,因为它要求结构“自相矛盾”。两者都没有错,但理解它们为何感觉不同,就是 JavaScript 从一堆方法的集合转变为一个你可以推理的系统的关键时刻。

Back to Blog

相关文章

阅读更多 »