왜 push와 pop은 자연스럽게 느껴지고 shift는 그렇지 않은가

발행: (2025년 12월 29일 오전 09:41 GMT+9)
8 min read
원문: Dev.to

Source: Dev.to

번역할 텍스트를 제공해 주시겠어요? 현재 제공된 내용은 소스 링크만 포함되어 있어 번역할 본문이 없습니다. 텍스트를 알려주시면 한국어로 번역해 드리겠습니다.

JavaScript 배열이 조용히 최적화하는 것

When I first started working with JavaScript arrays, push and pop felt immediately intuitive.
You add something to the end.
You remove something from the end.
Nothing surprising happens.

Then I started using shift.
It did exactly what it promised—it removed the first element—but it always felt heavier, slower, slightly uncomfortable in a way that was hard to articulate.

At first, I assumed that feeling was just intuition without
It was not.

배열은 앞을 바꾸기 전까지는 단순해 보인다

대부분의 사람들은 배열에 대해 아주 단순한 정신 모델을 가지고 시작합니다: 순서대로 배열된 깔끔한 아이템 목록이며, 필요에 따라 언제든지 수정할 수 있습니다. 이 모델은 배열의 앞부분을 수정하기 시작하기 전까지는 대부분 잘 작동합니다.

여기서 중요한 세부 사항이 드러납니다:

JavaScript 배열은 시작이 아니라 끝에 최적화되어 있습니다.

이를 이해하면 push, pop, shift 사이의 차이가 임의적으로 느껴지는 일이 사라집니다.

push가 수월하게 느껴지는가

push를 호출하면 엔진은 이미 다음 요소가 들어갈 위치를 알고 있습니다.

  • 명확한 끝이 있다.
  • 알려진 길이가 있다.
  • 다른 어떤 것도 이동할 필요가 없다.

값이 추가되고, 길이가 업데이트되며, 실행이 계속됩니다. 런타임 관점에서 이것은 협력적인 연산입니다. 배열의 구조와 함께 작동할 뿐, 그것에 반대되지 않습니다. 그래서 배열이 커져도 push가 저렴하고 예측 가능하게 느껴지는 것입니다.

Why pop feels just as natural

pop은 단순히 역연산이다.

  • 마지막 요소가 제거된다.
  • 길이가 감소한다.
  • 재배열이 필요하지 않다.

다시 말해, 배열에서 다른 어떤 것도 바뀔 필요가 없다. pushpop은 모두 구조의 경계에서 작동하며 가능한 적게 건드리며, 그 효율성은 사용감에도 반영된다.

shift는 다르게 느껴지는가

shift는 첫 번째 요소를 제거합니다. 겉보기엔 간단해 보이지만, 그 이면에는 복잡함이 있습니다.

인덱스 0에 있는 요소를 제거한다는 것은 나머지 모든 요소가 이동해야 함을 의미합니다. 남은 각 항목은 새로운 인덱스를 다시 할당받아야 합니다:

  • 1에 있던 것이 0이 됩니다.
  • 2에 있던 것이 1이 됩니다.
  • 그리고 계속해서…

배열은 재인덱싱되어야 합니다. 이것은 특이 현상이 아니라 배열이 작동하는 방식과 인덱스 접근이 유지되는 방식의 직접적인 결과입니다. 이를 깨달으면 shift에 대한 불편함이 이해됩니다—엔진에게 훨씬 더 많은 작업을 수행하도록 요구하기 때문입니다.

You can feel cost before you can name it

You do not need formal performance terminology to notice this difference. You feel it when:

  • Arrays grow larger
  • Operations happen repeatedly
  • Responsiveness starts to matter

Operations at the end scale quietly. Operations at the beginning scale loudly. This is one of those cases where understanding begins with experience, not vocabulary. Later, when performance concepts are introduced more formally, they feel familiar because the behaviour has already been observed.

배열은 구조화된 객체이며, 추상 리스트가 아니다

또 다른 도움이 되는 사고 전환은 JavaScript 배열이 추상적인 컨테이너가 아니라는 점을 기억하는 것입니다. 배열은 숫자 키와 길이 계약을 가진 구조화된 객체입니다. 각 인덱스는 속성입니다. 배열의 앞부분을 변경한다는 것은 한 번에 여러 속성을 변경하는 것을 의미합니다.

이렇게 보면 shift는 더 이상 pop의 형제가 아닙니다. 이는 근본적으로 다른 연산이며, 매우 다른 영향을 가집니다.

shift가 여전히 올바른 선택인 경우

이것이 shift가 잘못됐다는 뜻은 아니며, 의도적으로 사용해야 함을 의미합니다. 다음과 같은 경우에 shift를 사용하세요:

  • 배열이 작을 때
  • 연산이 드물게 일어날 때
  • 명확성이 순수 효율성보다 중요할 때

이 경우 shift는 완전히 허용됩니다. 비용을 이해한다는 것은 특정 메서드를 피하는 것이 아니라, 실수로가 아니라 의식적으로 선택하는 것입니다.

여기서 얻는 진짜 교훈

가장 중요한 핵심은 특정 배열 메서드에 관한 것이 아니라, 더 좋은 질문을 하는 법을 배우는 것입니다.

  • 아니오: “이게 작동하나요?”
  • 예: “이것이 런타임에게 무엇을 강요하나요?”

이 질문은 배열을 훨씬 넘어 확장됩니다. 다음과 같은 경우에도 나타납니다:

  • 문자열 조작
  • 객체 복사
  • 상태 업데이트
  • 부하가 걸렸을 때만 나타나는 성능 문제

이 질문을 스스로 하게 되면, JavaScript가 예측 불가능하게 느껴지던 것이 설명 가능하게 느껴집니다.

pushpop은 JavaScript 배열이 작동하도록 설계된 방식과 일치하기 때문에 자연스럽게 느껴집니다. shift는 구조 자체가 스스로와 싸우게 만들기 때문에 어색하게 느껴집니다. 어느 쪽도 틀린 것은 아니지만, 왜 다르게 느껴지는지를 이해하는 순간, JavaScript는 메서드들의 집합이 아니라 여러분이 논리적으로 파악할 수 있는 시스템이 됩니다.

Back to Blog

관련 글

더 보기 »

JavaScript 코드 성능을 향상시키는 방법

고성능 JavaScript는 예측 가능성에 관한 것입니다. 인간에게는 지루하지만 JIT 컴파일러에게는 즐거운 코드를 작성하세요. 성능은 마법이 아닙니다. 그것은 나입니다.