📢 어렵고 정석적인 개념 설명보다는 저같은 초보자도 이해하기 쉽게 정리하는 것을 원칙으로 포스팅하고 있습니다. 😄

[Javascript] 배열, 유사 배열 객체, 이터러블 객체 비교하기

이걸 왜 비교하나요?

배열은 우리가 자바스크립트를 사용하면서 굉장히 많이 쓰이는 구조 중 하나이다. 하지만, 배열에도 우리가 알고 있는 일반적인 배열이 있고 배열인 척하는 객체도 있고, 배열의 기능을 가진 객체도 있다. 우리가 배열을 자주 사용하는 이유에는 바로 반복문으로 요소를 순회 가능하기 때문이라는 점도 있을 텐데, 반복문을 사용할 때 어떤 건 for문이 되는 것도 있고 안 되는 것도 있고, 배열 메서드를 사용 못 하는 경우도 있기도 하고, 또 for~of문은 왜 되는 건지에 대해 모르고 넘어가는 경우 등 헷갈리는 경우가 많았을 것이다.

 

이번 기회에 배열 비스무리한 것들을 모두 정리하고, 또 그것들 사이에서 반복문은 어떤 게 사용 가능한 지 그리고 왜 그렇게 되는지에 대한 이유도 정리해보고자 한다.

 

배열 비스무리한 것들 정리하기

우선, 배열 비스무리한 것들을 총 3가지로 정리했다. 1) 일반 배열 2) 유사 배열 객체 3) 이터러블 객체이다.

이 3가지는 무조건 1가지 자격만 가질 수 있게 딱 구별되는 개념이라기보다는 이거이면서 저것도 되는 개념이기도 하다. (예를 들어, 일반 배열은 이터러블 객체이기도 하다.) 참고로, 여기서 말하는 객체는 리터럴 객체를 뜻하지 않는다.

 

일반 배열

우리가 배열하면 떠오르는 가장 일반적인 배열이다. 대괄호[ ]를 통해 선언한다. 딱히 부연설명은 하지 않겠다.

 

유사 배열 객체

유사 배열 객체는 배열처럼 인덱스로 요소에 접근할 수 있고, length 속성을 가지지만 실제로는 배열이 아닌 객체를 의미한다. 키값이 0, 1, 2, ...인 객체라서 마치 배열인 것처럼 인덱스에 접근할 수 있다. 유사 배열 객체의 종류로는 arguments, NodeList, HTMLCollection, 문자열 등이 있다.

🤔 NodeList와 HTMLCollection은 어떻게 다른 건데?
NodeList는 querySelectorAll의 반환값. HTMLCollection은 getElementsByClassName 등의 반환값.
NodeList의 요소는 DOM 노드이고, HTMLCollection의 요소는 HTML 요소이다.

배열이 아닌 객체이기 때문에 당연히 배열 메서드 사용이 불가능하며, 배열 메서드를 사용하기 위해서는 Array.from() 또는 Array.prototype.slice.call()과 같은 방법으로 유사 배열 객체를 배열로 변환해서 사용해야 한다.

 

이터러블 객체

이터러블 객체Symbol.iterator 메서드를 가지고 있는 객체로, 이터레이터를 반환하는 객체이다. 이터러블 객체에 대해서는 따로 정리한 글이 있으니 필요하다면 해당 글을 참고하고 오는 것이 좋다. (https://shawnkim.tistory.com/135)

 

일반 배열과 유사 배열 객체는 서로 겹치지 않는다. 다시 말해, 일반 배열이면서 유사 배열 객체일 수가 없다. 하지만, 이터러블 속성은 일반 배열에서도 가지고 있을 수 있고, 유사 배열 객체이면서도 가지고 있을 수 있다. 이터러블 객체의 대표적인 예시로는 배열, 문자열, Set, Map, NodeList 등이 있다.

 

배열 비스무리한 것들의 반복문 정리하기

객체 유형 for 문 배열 메서드 (forEach, map, filter 등) for~of 문
일반 배열 (Array) O O O
문자열 (String) O X O
arguments O X X
NodeList O X O
HTMLCollection O X O
Set X X (forEach는 가능) O
Map X X (forEach는 가능) O

우리가 자주 볼 수 있는 유형들을 다음과 같이 정리했다. 그리고, 해당 유형에 따라 어떤 반복문이 가능하고 가능하지 않는지도 표시해 보았다. 이 표를 보고 왜 이 유형에는 이게 되고 저거는 왜 안 되는지에 대한 이유를 설명할 수 있어야 한다. 그러려면 우선 각 반복문(메서드)에 대한 조건을 정리하고 가야 한다.

 

반복문의 가장 원초적이며 일반적인 방법인 for문의 작동 조건length 속성 유무와 인덱스로 요소에 접근 가능한 지의 여부이다. 웬만한 배열처럼 생긴 것들은 모두 length와 인덱스 구조를 가지고 있기 때문에, for문으로 순회가 가능하다. 하지만, Set과 Map 같은 경우는 배열이 아닌 이터러블 객체로, length를 가지고 있지 않으며 인덱스를 통해 요소에 접근이 불가능하다. 따라서, for문으로 순회할 수 없다.

 

사실 배열을 순회할 때는 for문보다는 forEach 메서드를 실무적으로는 많이 사용하는 것 같다. 여기서는 forEach 메서드뿐만 아니라 map, filter 등 다른 배열 메서드를 사용할 수 있는지의 여부 또한 포함하였다. 배열 메서드당연히 배열에서만 사용이 가능하다. 다른 형식에서 사용하려면 배열로 변환한 뒤 사용할 수 있다. 특이하게 Set, Map은 배열이 아닌데도 forEach를 사용할 수 있는데, 이것은 Set과 Map의 내장 메서드로 유일하게 forEach만 지원하는 것을 알 수 있다.

 

ES6에 이터러블 개념과 함께 도입된 반복문인 for~of문은 '이터러블'이라는 속성에 집중한다. 따라서, 이터러블 객체인 것만 대상으로 하며 이터러블 객체가 아닌 것은 동작하지 않는다. 웬만한 배열 비스무리한 것들은 대부분 이터러블 객체이다. 따라서, 웬만해서는 전부 for~of문으로 순회할 수 있으며, 유사 배열 객체의 HTMLCollection의 경우에만 브라우저 환경에 따라 이터러블 객체로 볼 수도 있고 아닐 수도 있기 때문에 이 점만 주의하면 된다.

 

1. 배열 비스무리한 것들에는 일반 배열, 유사 배열 객체, 이터러블 객체가 있다.
2. 그것들의 반복 방식에는 일반적인 for문 사용, 배열 메서드 사용, for~of 사용 등이 있다.
3. for문의 사용 조건은 반드시 length 속성이 있어야 하며, 인덱스로 요소에 접근할 수 있어야 한다.
4. 배열 메서드의 사용 조건은 반드시 배열이어야만 한다.
5. for~of문의 사용 조건은 반드시 이터러블 객체여야만 한다.