프로그래밍 언어에서 Collection 이란 단어는 '프로그래밍 언어가 제공하는 값을 담을 수 있는 컨테이너' 라고 생각합니다.
이전에 포스팅했던 객체(Object), 배열(Array), 형식화 배열(Typed Array)등이 있습니다.
ES5 이전까지는 Object와 Array만 있었지만 ES6 부터 Map, Set, WeakMap, WeakSet, Typed Array가 추가되었습니다.
이 포스팅에서는 Map, Set 컬렉션에 대해서 알아보겠습니다(Object, Array, Typed Array은 저번에 포스팅해서 넘어감)
맵(Map)은 키가 있는 데이터를 저장한다는 점에서 객체와 유사합니다. 다만, 맵은 키에 다양한 자료형을 허용
한다는 점에서 차이가 있습니다.
맵에는 다음과 같은 주요 메서드와 프로퍼티가 있습니다.
new 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.size
– 요소의 개수를 반환합니다.let map = new Map();
map.set('1', 'str1')
map.set(1, 'num1')
map.set(true, 'bool1')
alert( map.get(1) ); // 'num1'
alert( map.get('1') ); // 'str1'
alert( map.size ); // 3
객체를 키로 사용할 수 있다는 점은 맵의 가장 중요한 기능
중 하나입니다. 객체에는 문자열 키를 사용할 수 있습니다. 하지만 객체 키는 사용할 수 없습니다.
let john = { name: "John" };
let map = new Map();
map.set(john, 123);
alert(map.get(john)); // 123
다음 세 가지 메서드를 사용해 맵의 각 요소에 반복 작업
을 할 수 있습니다.
map.keys()
– 각 요소의 키를 모은 반복 가능한(iterable, 이터러블) 객체를 반환합니다.map.values()
– 각 요소의 값을 모은 이터러블 객체를 반환합니다.map.entries()
– 요소의 [키, 값]을 한 쌍으로 하는 이터러블 객체를 반환합니다. 이 이터러블 객체는 for..of반복문의 기초로 쓰입니다.let map = new Map([
['a', 1],
['b', 2],
['c', 2]
]);
console.log(map.keys())// [Map Iterator] { 'a', 'b', 'c' }
//for of문으로 key를 추출할 수 있다
for (let key of map.keys()) {
console.log(key)// "a", "b", "c"
}
이밖에도 다양한 기능들이 있습니다.
셋(Set)은 중복을 허용하지 않는 값을 모아놓은 특별한 컬렉션
입니다. 셋에 키가 없는 값이 저장
됩니다.
셋에는 다음과 같은 주요 메서드와 프로퍼티가 있습니다.
new Set(iterable)
– 셋을 만듭니다. 이터러블 객체를 전달받으면(대개 배열을 전달받음) 그 안의 값을 복사해 셋에 넣어줍니다.set.add(value)
– 값을 추가하고 셋 자신을 반환합니다.set.delete(value)
– 값을 제거합니다. 호출 시점에 셋 내에 값이 있어서 제거에 성공하면 true, 아니면 false를 반환합니다.set.has(value)
– 셋 내에 값이 존재하면 true, 아니면 false를 반환합니다.set.clear()
– 셋을 비웁니다.set.size
– 셋에 몇 개의 값이 있는지 세줍니다.셋 내에 동일한 값(value)이 있다면 set.add(value)을 아무리 많이 호출하더라도 아무런 반응이 없을 겁니다. 방문자 목록을 만들거나 중복을 피해야하는 데이터를 담을때 유용합니다.
let set = new Set();
let john = { name: "John" };
let pete = { name: "Pete" };
let mary = { name: "Mary" };
set.add(john);
set.add(pete);
set.add(mary);
set.add(john);
set.add(mary);
alert( set.size ); // 3
//아무리 중복으로 넣어도 값이 추가가 안됩니다.
for (let user of set) {
alert(user.name);//John, Pete, Mary
}
제네레이터(Generator)는 함수의 실행을 중간에 멈췄다가 재개할 수 있는 기능입니다.
function* fn(){
console.log(1)
yield 1;
console.log(2)
yield 2;
console.log(3)
yield 3;
return "finish";
}
const a = fn()
제네레이터는 함수명 옆에 *을 붙여서 만들고 내부엔 yield 키워드를 사용합니다. yield에서 함수의 실행을 멈출 수 있습니다.
a.next();//1 {value:1, done:false}
a.next();//2 {value:2, done:false}
a.next();//3 {value:3, done:false}
a.next();//{value:"finish", done:true}
a.next();//{value:undefined, done:true}
제네레이터안에는 next라는 메서드
가 있습니다. next는 가장가까운 yield를 만날때까지 진행되며 데이터 객체를 반환합니다. 여기서 value는 yield 오른쪽의 값이고 done은 yield가 마무리가 되었는지 안되었는지 확인하는 프로퍼티입니다. 만약 함수가 끝났어도 계속 next를 호출하면 value는 undefined를 반환합니다.
a.next();//1 {value:1, done:false}
a.return("끝임")//{value:""끝임", done:true}
a.next();//{value:undefined, done:true}
return메서드를 호출하면 그 즉시 제네레이터는 done:true가 됩니다.
for(let num of a){
console.log(num)//4 5 6
}
제네레이터도 이터러블 객체이므로 순회할 수 있습니다.
function* fn(){
const num01 = yield "첫번째";
console.log(num01)
const num02 = yield "두번째";
console.log(num02);
return num01 + num02:
}
const a = fn()
제네레이터는 외부로부터 값을 받을 수 있습니다.
a.next();//{value:"첫번째", done:false}
a.next(2)//2 {value:"두번째", done:false}
a.next(4)//4 {value:6, done:true}