Array[index] 사용을 그만둬라 애송이

작성일:2024.03.24|조회수:0

Array[index] 사용을 그만둬라 애송이

이 포스트는 Timotius Sitorus가 자신의 dev.to 블로그에 올린 Stop using Array[index], use Array.at() instead 게시글을 번역한 것이다. 번역하는 과정에서 다소 의역이 있을 수 있으며, 일부 번역에는 사견이 포함되어있기도 하다.

Array.at() 메소드는 ECMAscript2022를 통해 새롭게 추가된 Array 생성자의 프로토타입 메소드입니다. 이 메소드를 통해 우리는 마침내 JS에서 기본적으로 Negative Indexing을 처리할 수 있게 되었습니다.

Negative Indexing

네거티브 인덱싱이라 함은 음수를 인덱스로 사용하여 배열의 시작이 아닌 끝에서부터 특정 요소에 엑세스하는 기능입니다. 예를 들어 파이썬에서는 배열의 마지막 요소에 접근하고 싶은 경우 list[-1]과 같은 방식으로 작업을 수행할 수 있습니다.

그러나 JS의 array는 이런 식으로 작동하지 않습니다. 대괄호 표기법이 array나 string에 속한 것이 아니라 모든 object에 속하기 때문에 ─ 이 부분에 대해서 따로 확인해본 것은 아니지만 이러한 표기법을 지원하는 프로퍼티가 object 생성자의 prototype에 존재하는 것이 아닐까 추측한다 ─ 그렇습니다.

object에서 대괄호 표기법을 사용할 경우 해당 key를 사용하여 객체의 value를 얻는 것을 의미합니다. 배열과 문자열 역시 객체이기 때문에, 이러한 자료형들에서도 동일한 작동을 보이는 것입니다. 내부적으로 배열과 문자열은 각 요소를 현재 인덱스와 일치하는 키에 할당합니다.

JS
// 인덱싱 방식에 관해서라면 arr는 obj와 완전히 동일하게 동작한다
const arr = ['cat', 'dog', 'fish', 'bird'];
 
const obj = {
   0: 'cat',
   1: 'dog',
   2: 'fish',
   3: 'bird'
};

따라서 arr[-1]은 이미 유효한 JS이지만 마지막 요소를 반환하는 것이 아닌 배열의 "-1" key에 해당하는 value를 반환하려고 시도합니다. 그리고 이러한 경우 JS는 당연하게도 ─ "-1" key가 없으니 ─ undefined를 반환하게 될 것입니다.

 

기존의 해결 방법

기존 JS에서는 네거티브 인덱싱을 지원하지 않지만, 이를 흉내내는 기법 몇 가지가 널리 알려져있습니다. 아마도 가장 유명한 기법은 배열의 길이에서 음수 인덱스만큼 뺀 값을 사용하는 것입니다.

JS
const pets = ['cat', 'dog', 'fish', 'bird'];
const lastPet = pets[pets.length - 1];
 
console.log(lastPet); // Prints out 'bird'

대부분의 개발자가 네거티브 인덱싱을 흉내내기 위해 사용하는 기법이지만, 여기에는 몇 가지 문제가 있습니다.

CSS
['cat', 'dog', 'fish', 'bird'][ **what do you put here** - 1];
 
const a = () => ['cat', 'dog', 'fish', 'bird']; 
a()[ **What do you out here** - 1];

다른 방식으로는 Array.slice() 메소드가 네거티브 인덱싱을 지원한다는 점을 이용할 수 있습니다.

JS
const pets = ['cat', 'dog', 'fish', 'bird'];
const lastPet = pets.slice(-1)[0];
 
console.log(lastPet); // Prints out 'bird'

이 방법은 앞서 언급한 많은 문제를 해결하지만, 몇 가지 새로운 문제를 일으킵니다.

 

Array.at()

at 메소드는 위에서 언급한 다양한 문제를 해결하기 위해 구현되었습니다. 아규먼트로 양수를 넣을 경우 Array[index]와 정확히 동일한 작동을 보장하면서, 아규먼트로 음수를 넣는 경우에는 네거티브 인덱싱을 완벽하게 구현해냅니다.

JS
const pets = ['cat', 'dog', 'fish', 'bird'];
const lastPet = pets.at(-1);
 
console.log(lastPet); // Prints out 'bird'

이 메소드를 사용하므로써 네거티브 인덱싱을 흉내내는 이전의 방식들을 대체할 수 있으며, 더 깔끔한 구문을 제공하며, 성능 저하가 발생하지도 않습니다. 필요한 경우 polyfill을 사용할 수 있으며, 대부분의 최신 브라우저에서 at 메소드를 사용할 수 있습니다.

더 읽어보기

  • 2026.03.13

    Streams API 3. 바이트 스트림과 실전 파이프라인

    앞선 두 글에서 우리는 Web Streams API의 표면과 의미론을 정리했다. 이제 남은 질문은 하나이다. 이 지식을 실제 어디에 써먹을 것인가. 이 질문에 답하는 순간 스트림 학습은 비로소 완성된다. 표준을 읽고 메서드를 아는 것만으로는 충분하지 않다. fetch() 응답 본문을 어…

  • 2026.03.13

    Streams API 2. 상태와 백프레셔의 의미론

    스트림을 처음 배울 때는 읽고 쓰는 예제가 꽤 단순해 보인다. getReader()로 읽고, getWriter()로 쓰고, pipeTo()로 연결하면 끝나는 것처럼 느껴진다. 실제로 짧은 데모는 이 정도만 알아도 돌아간다. 그러나 실무에서 스트림 코드를 망가뜨리는 원인은 거의 언제나 더…

  • 2026.03.13

    Streams API 1. 읽기와 쓰기의 출발점

    자바스크립트에서 비동기를 배울 때 우리는 대개 Promise와 async, await부터 익힌다. 이 조합은 한 번의 결과를 기다리는 문제에는 매우 강력하다. 그러나 데이터가 한 번에 끝나지 않고 계속 흘러들어오는 상황에서는 이야기가 달라진다. 네트워크 응답이 길게 이어지거나, 큰 파일…

  • 2026.04.11

    Trie 자료구조

    문자열 데이터를 다룰 때 단순히 “이 단어가 있나?”만으로는 부족한 순간이 있다. 자동 완성처럼 특정 접두사로 시작하는 후보를 모아야 할 때도 있고, 어떤 키에 값을 두고 빠르게 찾고 싶을 때도 있다. 이럴 때 가장 자연스럽게 떠올릴 수 있는 자료구조가 바로 Trie이다.Trie는 무엇…

  • 2026.03.19

    Streams API 부록 2. 왜 이미지는 위에서 아래로 나타날까

    웹 페이지에서 이미지를 로드할 때 흥미로운 장면을 종종 볼 수 있다. 이미지가 한 번에 완전히 나타나는 것이 아니라, 위에서 아래로 조금씩 채워지면서 나타나는 경우가 있기 때문이다. 특히 네트워크가 느리거나 이미지가 큰 경우 이런 현상이 더 분명하게 보인다. 마치 이미지가 위쪽부터 스캔…

댓글

댓글을 불러오는 중...