ES6에서 새로 도입한 데이터 구조 map, set

맵은 키와 값을 연결한다는 점에서 객체와 비슷하고, 셋은 중복을 허용하지 않는다는 점을 제외하면 배열과 비슷

MAP

ES6이전에는 키와 값을 연결하려면 객체를 사용해야 했음. 하지만 객체를 이런 목적으로 사용하면 여러가지 단점이 생김

  • 프로토타입 체인 때문에 의도하지 않은 연결이 생길 수 있음
  • 객체 안 연결된 키와 값이 몇 개나 되는지 쉽게 알아낼 방법이 없음
  • 키는 반드시 문자열이나 심볼이어야 하므로 객체를 키로 써서 값과 연결할 수 없음
  • 객체는 프로퍼티 순서를 전혀 보장하지 않음

map은 키와 값을 연결할 목적이라면 객체보다 나은 선택

1
2
3
4
const n1 = {name:'shin'};
const n2 = {name:'jane'};
const n3 = {name:'jin'};
const n4 = {name:'tt'};

map

먼저 맵을 만듭니다.

1
const userRoles = new Map();

set()

다음에는 맵의 set() 메서드를 써서 사용자의 역할을 할당

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
userRoles.set(u1, 'user');
userRoles.set(u2, 'user');
userRoles.set(u3, 'admin');
//tt는 역할 없음
//set() 메서드는 체인으로 연결할 수 있어서 타이핑의 수고를 덜어줌
userRoles
.set(u1, 'user')
.set(u2, 'user')
.set(u3, 'admin');
//생성자에 배열의 배열을 넘기는 형태로 써도 됨
const userRoles = new Map([
[u1, 'user'],
[u2, 'user'],
[u3, 'admin'],
]);

get()

이제 u2의 역할을 알아볼 때는 get()메서드를 쓰면 됨.

1
userRoles.get(u2); //"user"

맵에 존재하지 않는 키에 get을 호출하면 undefined를 반환.


has()

맵에 키가 존재하는지 확인하는 has()메서드

1
2
3
4
userRoles.has(u1); //true
userRoles.get(u1); //"user"
userRoles.has(u4); //false
userRoles.get(u4); //undefined

맵에 이미 존재하는 키에 set()을 호출하면 값이 교체됨

1
2
3
userRoles.get(u1); //user
userRoles.set(u1, 'admin');
userRoles.get(u1); //admin


size()

size프로퍼티는 맵의 요소 갯수를 반환

1
userRoles.size; //3


keys(),values(), entries()

key메서드는 맵의 키,
values 메서드는 값,
entries 메서드는 첫번째 요소가 키값이고 두번째 요소가 값인 배열을 반환
이 메서드가 반환하는 것은 모두 이터러블 객체여서 for...of루프를 쓸 수 있음

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
for(let u of userRoles.keys())
console.log(u.name);
for(let r of userRoles.values())
console.log(r);
for(let ur of userRoles.entries())
console.log(`${ur[0].name}: ${ur[1]}`);
//맵도 분해할 수 있음
for(let [u, r] of userRoles.entries())
console.log(`${u.name}: ${r}`);
//entries()메서드는 맵의 기본 이터레이터.
//위 코드는 다음과 같이 단축해서 쓸 수 있음
for(let [u, r] of userRoles)
console.log(`${u.name}: ${r}`);

이터러블 객체보다 배열이 필요하다면 확산 연산자를 쓰면 됨

1
[...userRoles.values()]; //["user", "user", "admin"]


delete()

맵의 요소를 지울 떄 사용

1
2
userRoles.delete(u2);
userRoles.size; //2


clear()

맵의 요소를 모두 지울 때 사용

1
2
userRoles.clear();
userRoles.size; //0

위크맵

WeakMap은 다음 차이점을 제외하면 Map과 완전히 같음

  • 키는 반드시 객체여야 한다.
  • WeakMap의 키는 가비지 콜렉션에 포함될 수 있다.
  • WeakMap은 이터러블이 아니며 clear()메서드도 없음

일반적으로 자바스크립트 코드는 코드 어딘가에서 객체를 참고하는 한 객체의 메모리를 계속 유지하려고 하는데 WeakMap은 그렇지 않음. 가비지 콜렉션 중인 객체를 노출할 위험이 큼

WeakMap의 이런 특징은 객체 인스턴스의 전용 키를 저장하기에 알맞음

1
2
3
4
5
6
7
8
9
10
11
const secretHolder = (function() {
const secret = new WeakMap();
return class{
setSecret(secret){
secret.set(this, secret);
}
getSecret(){
return secret.get(this);
}
}
})();

비밀을 저장할 때는 setSecret, 보려고 할 때에는 getSecret

1
2
3
4
5
6
7
8
const a = new secretHolder();
const b = new secretHolder();
a.setSecret('secret A');
b.setSecret('secret B');
a.getSecret(); //"secret A"
b.getSecret(); //"secret B"

일반적인 Map을 써도 되지만 그렇게 하면 secretHolder 인스턴스에 저장한 내용은 가비지 콜렉션에 포함되지 않음. 가지비 콜렉션에 추가하고 싶으면 WeakMap(?)

Set

Set은 중복을 허용하지 않는 데이터 집합.
같은 사용자에게 같은 역할을 여러번 부여한다는 것은 상식적이지 않음. 셋은 이런 경웨 이상적인 데이터 구조

1
2
3
4
5
6
7
8
9
10
const roles = new Set();
//사용자 역할을 추가할 때에는 add()메서드를 사용
roles.ass("user"); //Set ["user"]
//사용자에게 관리자 역할을 추가하려면 add()
roles.add("admin"); //Set ["user", "admin"]
//map과 마찬가지로 Set에도 size프로퍼티가 있음
roles.size; //2

추가하려는 것이 이미 셋에 있는지 확인할 필요 없음. 이미 있다면 아무 일도 일어나지 않음

1
2
roles.add("user"); //Set ["user", "admin"]
roles.size; //2

역할을 제거하고 싶을 떄에는 delete()
제거에 성공했다면(그런 역할이 셋에 존재했다면) true반환, 아니면 false

1
2
3
roles.delete("admin"); //true
roles; //Set ["user"]
roles.delete("admin"); //false


WeakSet

위크셋은 객체만 포함 할 수 있으며, 이 객체들은 가비지 콜렉터의 대상이 됨.
WeakMap과 마찮가지로 WeakSet도 이터러블이 아님

위크셋의 용도는 매우 적음.
실제 용도는 주어진 객체가 셋 안에 존재하는지 아닌지를 알아보는 것 뿐 이라고 해도 과언이 아님

EX) 산타클로스가 jingjing라는 WeakSet을 가지고 어떤 아이가 우는 아이인지 확인해서 선물대신 석탄(도 가격이 올랐다던데)을 놓고 온다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const jingjing = new WeakSet();
const children = []
{name: "suzy"},
{name: "shin"}
];
jingjing.add(children[1]);
for(let child of children){
if(jingjing.has(child))
console.log(`Coal for ${child.name}!`);
else
console.log(`Presents for ${child.name}!`);
}
공유하기 댓글