September 15, 2021

키를 사용해 식별할 수 있는 값을 담은 컬렉션은 객체라는 자료구조를 이용해 저장하는데, 객체만으로도 다양한 작업을 할 수 있습니다.

그런데 개발을 진행하다 보면 첫 번째 요소, 두 번째 요소, 세 번째 요소 등과 같이 순서가 있는 컬렉션이 필요할 때가 생기곤 합니다. 사용자나 물건, HTML 요소 목록같이 일목요연하게 순서를 만들어 정렬하기 위해서 말이죠.

순서가 있는 컬렉션을 다뤄야 할 때 객체를 사용하면 순서와 관련된 메서드가 없어 그다지 편리하지 않습니다. 객체는 태생이 순서를 고려하지 않고 만들어진 자료구조이기 때문에 객체를 이용하면 새로운 프로퍼티를 기존 프로퍼티 ‘사이에’ 끼워 넣는 것도 불가능합니다.

이럴 땐 순서가 있는 컬렉션을 저장할 때 쓰는 자료구조인 배열을 사용할 수 있습니다.

성능

push와 pop은 빠르지만 shift와 unshift는 느립니다.

배열 앞에 무언가를 해주는 메서드가 배열 끝에 무언가를 해주는 메서드보다 느린 이유를 실행 흐름을 살펴보면서 알아봅시다.

반복문

for..of를 사용하면 현재 요소의 인덱스는 얻을 수 없고 값만 얻을 수 있습니다. 이 정도 기능이면 원하는 것을 충분히 구현할 수 있고 문법도 짧기 때문에 배열의 요소를 대상으로 반복 작업을 할 땐 for..of를 사용해 보시기 바랍니다.

배열은 객체형에 속하므로 for..in을 사용하는 것도 가능합니다.

let arr = ["사과", "오렌지", "배"];

*for (let key in arr) {*alert( arr[key] ); // 사과, 오렌지, 배
}

그런데 for..in은 다음과 같은 특징을 지니기 때문에 배열에 for..in을 사용하면 문제가 발생하므로 되도록 다른 반복문을 사용하시길 바랍니다.

  1. for..in 반복문은 모든 프로퍼티를 대상으로 순회합니다. 키가 숫자가 아닌 프로퍼티도 순회 대상에 포함됩니다.

    브라우저나 기타 호스트 환경에서 쓰이는 객체 중, 배열과 유사한 형태를 보이는 ‘유사 배열(array-like)’ 객체가 있습니다. 유사 배열 객체엔 배열처럼 length 프로퍼티도 있고 요소마다 인덱스도 붙어 있죠. 그런데 여기에 더하여 유사 배열 객체엔 배열과는 달리 키가 숫자형이 아닌 프로퍼티와 메서드가 있을 수 있습니다. 유사 배열 객체와 for..in을 함께 사용하면 이 모든 것을 대상으로 순회가 이뤄집니다. 따라서 ‘필요 없는’ 프로퍼티들이 문제를 일으킬 가능성이 생깁니다.

  2. for..in 반복문은 배열이 아니라 객체와 함께 사용할 때 최적화되어 있어서 배열에 사용하면 객체에 사용하는 것 대비 10~100배 정도 느립니다. for..in 반복문의 속도가 대체로 빠른 편이기 때문에 병목 지점에서만 문제가 되긴 합니다만, for..in 반복문을 사용할 땐 이런 차이를 알고 적절한 곳에 사용하시길 바랍니다.

그러니 배열엔 되도록 for..in를 쓰지 마세요.