[Javascript] Object, Map, Set (+iterable 객체, iterator)

박세화·2024년 1월 20일
0

Javascript

목록 보기
10/12

객체(Object)란?

자바스크립트에는 여덟 가지 자료형이 있는데, 이 중 일곱 개는 하나의 데이터만 담을 수 있어 원시형(primitive type) 이라 불린다.
하지만 객체는 유일하게 데이터 컬렉션이나 복잡한 개체를 표현할 수 있다.

  • 객체엔 key-value 쌍으로 구성된 프로퍼티를 여러 개 넣을 수 있다.

  • key엔 문자형만이(+심볼), value엔 모든 자료형이 허용된다

✅ key에 숫자를 담아도 객체 내부적으로 이를 문자열로 변환한다.

  • 다른 언어와는 달리, 자바스크립트에선 존재하지 않는 프로퍼티에 접근하려 해도 에러가 발생하지 않고 undefined 를 반환한다.

  • 그리고 배열과 비교해보자면, 배열은 저장된 데이터들이 순서를 가지고 있는데 반해 객체는 순서를 저장하지 않는다.

💡 객체나 배열의 단점을 보완하기 위한 새로운 자료구조로 ES6 에서 MapSet이 등장하게 되었다!


📌 Map 객체

Map은 결국 객체의 일종이기 때문에 객체와 매우 유사하다. 하지만 몇 가지 중요한 차이점들이 있다.

✔️ Map과 객체의 비교점을 표로 작성해보았다.

빨간색으로 표시된 것들이 중요한 차이점들이다.

  • 객체와 달리 Map에서는 key에 다양한 타입의 자료형이 허용된다. 심지어 key 값에 객체가 들어올 수도 있다.
    따라서 이런 식의 데이터 구성이 가능하다!
  • 맵은 값이 삽입된 순서대로 순회를 실시한다. 객체가 프로퍼티 순서를 기억하지 못하는 것과는 다르다!

  • 내장형 생성자로 Map 객체를 만들 때, 인자에는 배열과 같은 이터러블 객체를 넣어야 한다.
    위 예시에서도 작은 배열 두 개가 들어있는 큰 배열 한 개를 인자로 넘겨주었다.


✅ Map은 객체와 달리 이터러블이다

이터러블은 [Symbol.iterator] 이라는 내장 심볼(Symbol) 을 가진 객체들을 말한다.
(밑에서 더 자세히 설명)

Map의 프로토타입 내부에 내장 심볼 Symbol.iterator 가 들어있는 것을 확인할 수 있다.


📌 Set 객체

Set은 배열과 유사하지만 중복을 허용하지 않는 값을 모아놓은 특별한 컬렉션이다. 수학에서의 집합과 같은 개념이다.

  • 중복되지 않는 유일한 값들의 집합이다. 같은 값이 들어있을 경우 한 개로 인식된다.

  • 요소 순서에 의미가 없다.

  • 인덱스가 존재하지 않으며, 그렇기에 요소 접근이 불가능하다.


✅ Map, Set, 배열은 모두 이터러블이다

위에서 Map을 확인했던 것과 마찬가지로, Set의 프로토타입 내에도 내장 심볼 Symbol.iterator 가 들어있는 것을 확인할 수 있다.


📌 이터러블(iterable) 객체란?

  • Symbol.iterator 이라는 내장 심볼(Symbol) 을 가진 객체들

  • iterator 객체를 리턴해야 한다. (👉 관련글)

  • JavaScript 엔진은 이 심볼을 키로 갖는 메소드가 정의된 객체를 iterable 객체로 인식한다. iterable 객체로 인식되는 객체들만 for ... of 문법 등을 이용한 반복이 가능하다.
    ➡️ 배열, 문자열, Map, Set 등이 이터러블 객체이다.

💡 심볼(Symbol) 이란?
ES6 에서 새롭게 추가된 원시 자료형으로서, 객체의 고유한 프로퍼티 키를 만들 때 사용된다.
Symbol 함수를 이용하여 직접 심볼을 생성하고 사용할 수도 있다.
💡 내장 심볼
특별한 용도로 사용되기 위해 JavaScript 엔진 내에 미리 생성되어 상수로 존재하고 있는 심볼이다. 이들은 Symbol 함수의 프로퍼티로서 존재한다(Symbol 함수도 객체의 일종이기 때문에 프로퍼티를 가질 수 있음).


📌 for in문 vs for of문

위에서 이터러블 객체만이 for of 문을 사용할 수 있다고 언급했다. 자바스크립트에서 요소들을 반복하기 위해선 for in문을 사용하는 방법도 있는데, 이 둘은 약간의 차이가 존재한다.

💡 결론부터 말하면 for in문은 객체에, for of문은 배열, Map, Set 등에 사용된다.

for...in

for in 자바스크립트의 기본적인 반복문 구문이다. 모든 객체에서 사용이 가능하고, 객체의 모든 열거 가능한 속성을 반복한다.

  • 중요한 건 for in 구문은 객체의 key 값에는 접근할 수 있지만, value 값에 접근할 수는 없다는 점이다.😧
    그 증거로, 배열에 for in 을 쓰면 인덱스 값이 나오는 것을 확인할 수 있다. 사실 자바스크립트에서는 배열도 (큰 의미의) 객체이기 때문에, 그 객체의 key 값에 해당하는 것이 나오는 것이다.
  • 또한, for in 반복문은 순서 없이 반복이 되는 특징을 가진다.
    배열은 인덱스의 순서가 중요한 객체인데, 만약 for in을 배열에 사용하면 인덱스 순서대로 반복한다는 결과를 보장할 수 없다.

    위 예시 코드로 살펴보면, array라는 배열을 for in으로 반복하는 경우, 눈에 보이는 배열의 원소 뿐만 아니라, 눈에 보이지 않는 프로토타입 속성의 인덱스까지 모두 돌며 반복하는 것을 알 수 있다. 게다가 objCustom을 먼저 정의해주었지만, arrCustom이 먼저 출력되어버렸다.
    (그래서 인덱싱의 순서를 보장할 수 없다는 의미!)

💡 for in은 배열에서 쓰지 말고, 순서가 없는 Object 자료형에서 사용하는 게 좋다!

for...of

for in 문의 단점을 보완하기 위해 ES6에 for of 문이 추가되었다!

  • for of 반복문은 [Symbol.iterator] 속성을 가지고 있는 컬렉션 객체에서만 사용 가능하다.
    (또는 [Symbol.iterator]를 직접 명시하여 사용할 수도 있다)
    이유는 for of 문이 이터러블 안의 이터레이터를 실행시키기 때문이다.
    ➡️ 배열, Map, Set, 문자열 등에 사용 가능!

  • 순회 가능한(iterable) 객체의 요소를 순차적으로 접근하는 데 사용된다. for in이 순서를 무시하고 반복할 위험성이 있는데 반해, for of 는 요소의 순서를 보존하면서 순회한다.

위에서 for in으로 반복했을 땐 원하지 않는 것들까지 모두 출력됐었지만, for of 을 사용하니 원하는 요소들만 반복된 것을 볼 수 있다.

Map에도 사용해보자

이처럼 Map 객체에 for of 를 사용하여 프로퍼티들을 출력할 수 있다

하지만 같은 Map 객체에 for in을 써보면 undefined 를 반환한다.


for in과 for of의 비교


출처
[모던 자바스크립트 Deep Dive] 34. Set 과 Map
[ES6] Map vs Object 비교(번역)
객체
자바스크립트 for in vs for of 반복문 정리
[JavaScript] 심볼 (Symbol) 타입 이해하기
[Javascript] 반복문 for.. in 과 for.. of 의 차이
출처: https://kincoding.com/entry/Javascript-반복문-for-in-과-for-of-의-차이

자바스크립트 for…in 문과 for…of 문의 차이

0개의 댓글