WeakMap
WeakMap은 다음 차이점을 제외하면 Map과 완전히 같습니다.
- 키는 반드시 객체여야 합니다.
- WeakMap의 키는 가비지 콜렉션(GC)에 포함될 수 있습니다.
- WeakMap은 이터러블이 아니며 clear() 메서드도 없습니다.
일반적으로 자바스크립트는 코드 어딘가에서 객체를 참조하는 한 그 객체를 메모리에 계속 유지합니다. 예를 들어 Map의 키인 객체 o가 있다면, 자바스크립트는 Map이 존재하는 한 o를 메모리에 계속 유지합니다. WeakMap에서는 그렇지 않습니다. 따라서 WeakMap은 이터러블이 될 수 없습니다. 가비지 콜렉션 중인 객체를 노출할 위험이 너무 크기 때문입니다.
WeakMap의 이런 특징은 객체 인스턴스의 전용private키를 저장하기에 알맞습니다.
const SecretHolder = (function() {
const secrets = new WeakMap();
return class {
setSecret(secret) {
secrets.set(this, secret);
}
getSecret() {
return secrets.get(this);
}
}
})();
앞의 예제이서는 WeakMap과 그 WeakMap을 사용하는 클래스를 함께 IIFE(즉시 실행 함수)에 넣었습니다. IIFE 외부에서는 그 인스턴스에 비밀스런 내용을 저장할 수 있는 SecretHolder 클래스를 얻게 됩니다. 비밀을 저장할 때는 setSecret 메서드를 써야만 하고, 보려 할 때는 getSecret 메서드를 써야만 합니다.
const a = new SecretHolder();
const b = new SecretHolder();
a.setSecret('secret A');
b.setSecret('secret B');
console.log(a.getSecret()); // secret A
console.log(b.getSecret()); // secret B
일반적인 Map을 써도 되지만, 그렇게 하면 SecretHolder 인스턴스에 저장한 내용은 가비지 콜렉션에 포함되지 않습니다.