Java에서는 배열을 사용하다가 생기는 비효율적인 문제를 해결하기 위해서 자료구조를 사용하기 위한 “컬렉션 프레임워크"라는 개념이 있다.
Javascript에서도 객체와 배열만으로 해결하기 힘든 부분들을 위해서 Map
과 Set
이 등장하였다.
: 데이터와 키를 같이 저장할 수 있는 자료구조이다.
주요 메서드와 프로퍼티 :
new Map() // map을 만든다
map.set(key, value) // key를 이용해 value를 저장한다
map.get(key) // key에 해당하는 값 반환. key가 존재하지 않다면 undefined를 반환
map.has(key) // key가 존재하면 true, 아니면 false를 반환
map.delete(key) // key에 해당하는 값 삭제
map.clear() // map 안의 모든 요소 제거
map.size // 요소의 개수 반환
map.keys() // 각 요소의 키를 모아둔 iterable 객체를 반환
map.values() // 각 요소의 값을 모은 iterable 객체를 반환
map.entries() // 요소의 [key, value] 한 쌍으로 하는 iterable 객체 반환. 이 객체는 for...of 루프의 기초로 쓰인다
for...of
루프의 [key, value]
배열을 반환한다NaN
도 key로 쓸 수 있다sameValueZero
알고리즘을 기반으로 한다: 중복이 존재할 수 없는 자료구조이다. 어떤 값이라도 그 Set
콜렉션 내에서 유일하다
주요 메서드:
new Set(iterable) // set을 만든다. iterable 객체를 전달받으면(대게 배열) 그 안의 값을 복사해서 set에 넣어준다
set.add(value) // value를 추가하고 set 자신을 반환
set.delete(value) // value 제거. 호출 시점에 set 내에 value가 있어서 제거에 성공하면 true, 아니라면 false를 반환
set.has(value) // set 내에 값이 존재하면 true, 아니면 false
set.clear() // set 비우기
set.size // set에 몇 개의 값이 있는지 count
set.keys() // set 내의 모든 값을 포함하는 iterable 객체 반환
set.values() // set.keys와 동일한 작업을 한다. map과의 호환성을 위해 만들어진 메서드
set.entries() // set 내의 각 값을 이용해서 만든 [value, value] 배열을 포함하는 iterable 객체 반환. map과의 호환성을 위해 만들어졌다
NaN
과 undefined
도 Set
에 저장할 수 있다Array
에 비해 훨씬 빠르다→ Array
는 배열, 무언가를 나열할 수 있기 때문에 다양한 타입이 오기도 하고 중복되는 같은 값이 올 수 있다. Set
은 중복되지 않은 값들을 모아둔 집합이다. 여러개의 값들을 나열한 Array
와 그 중에서 중복된 것들을 제거한 것이 Set
이기 때문에 조회에 있어서 훨씬 빠르다고 할 수 있다.
→ Set
의 value에 반복 작업 하기 위해서 for...of
나 forEach
를 사용한다. 이 때 forEach
를 사용하려면,
set.forEach((value, valueAgain, set) => {
alert(value);
});
와 같이 사용하게 되는데 forEach
에 쓰인 콜백 함수의 세 개의 인수 중 첫 번째 값과 두 번째 값은 동일한 값이다. 이렇게 구현된 이유는 map
과의 호환성 때문이다. 따라서 map
과의 호환성을 띄고 있기 때문에 map
을 set
으로 혹은 set
을 map
으로 교체하기가 쉽다.
자바스크립트는 추후 사용될 가능성이 있는 값을 메모리에 유지한다(garbage collection 참고). 객체의 프로퍼티나 배열의 요소, map
이나 set
을 구성하는 요소, 즉 자료구조를 구성하는 요소도 자신이 속한 자료구조가 메모리에 남아있는 동안 도달 가능한 값으로 취급되어 메모리에서 삭제되지 않는다.
그러나 WeakMap
을 사용하면 키로 쓰인 객체가 garbage collection의 대상이 된다.
Map
과의 차이 :
Object
타입만 사용할 수 있다. 원시값은 불가능WeakMap
의 key 로 사용된 객체를 참조하는 것이 아무것도 없다면 해당 객체는 메모리와 WeakMap
에서 자동으로 삭제된다keys()
, values()
, entries()
메서드를 지원하지 않는다. 따라서 key 나 value 전체를 얻는게 불가능하다// WeakMap이 지원하는 메서드
weakMap.get(key)
weakMap.set(key, value)
weakMap.delete(key)
weakMap.has(key)
적은 메서드만 제공하는 이유: Garbage collection이 정확히 일어나는 시점을 알 수 없으므로 요소(key, value) 전체를 대상으로 무언가를 하는 메서드는 동작 자체가 불가능하다.
Set
과의 차이 :
Object
만 저장할 수 있다. 원시값은 저장할 수 없다Set
안의 객체는 도달 가능할 때만 메모리에서 유지된다add
, has
, delete
를 사용할 수 있고 size
, keys()
나 반복 작업 관련 메서드는 사용할 수 없다WeakMap
과 WeakSet
의 가장 큰 단점은 iterable 하지 않다는 점이다. 저장된 자료를 한번에 얻는게 불가능하다. 그래서 객체와 함께 추가 데이터를 저장하는 용도로 쓸 수 있다.
Map
과Set
에 반복 작업을 할 때, 해당 컬렉션에 요소나 값을 추가한 순서대로 반복 작업이 이루어진다. 이 두 컬렉션은 정렬이 되어있지 않다고 할 수 없으나 요소나 값을 재 정렬 하거나 (배열에서 인덱스를 이용해서 요소를 가져오는 것처럼) 숫자를 이용해 특정 요소나 값을 가지고 오는 것은 불가능하다.
*원시값: 객체가 아니면서 메서드도 가지지 않는 데이터. 7 종류가 존재하는데 string, number, bigint, boolean, undefined, symbol, 그리고 null 이 존재한다. 모든 원시 값은 불변하기 때문에 변형시킬 수 없다.
References :
코어 자바스크립트 맵과 셋
코어 자바스크립트 위크맵과 위크셋
키기반의 컬렉션
Javascript Set 그리고 Map