Zustand와 Jotai를 공부하여 내부 구성 코드를 보던 중, weakMap을 사용한 것을 보게 되었다. 개념은 알고 있었지만 실무에서는 잘 사용하지 않았던 내장 객체라 좀 더 눈길이 가게 되어 자세히 알아보았다...
JavaScript Map 객체는 기존 객체와는 다르게 key 값으로 모든 형태의 JavaScript 값이 올 수 있다는 점이 가장 큰 차이점이다.
<script>
// Map 생성
const map = new Map();
// 키로 사용할 객체
const user = { name: 'Alice' };
// 데이터 추가 (set)
map.set('name', 'Bob'); // 문자열 키
map.set(1, 'one'); // 숫자 키
map.set(true, 'isTrue'); // 불리언 키
map.set(user, { role: 'admin' }); // 객체 키
// 데이터 조회 (get)
console.log(map.get('name')); // "Bob"
console.log(map.get(user)); // { role: 'admin' }
// 크기 확인 (size)
console.log(map.size); // 4
// 키 존재 여부 확인 (has)
console.log(map.has(1)); // true
// 데이터 삭제 (delete)
map.delete(1);
console.log(map.size); // 3
// 순회 (forEach)
map.forEach((value, key) => {
console.log(`키: ${key}, 값: ${value}`);
});
</script>
WeakMap은 Map과 매우 유사하지만, key로 오직 객체만을 사용할 수 있으며, 키에 대한 약한 참조(weak reference)를 한다는 결정적인 차이가 있다.
<script>
let user = { name: 'John' };
const weakMap = new WeakMap();
// 데이터 추가 (set)
weakMap.set(user, 'some metadata');
// 데이터 조회 (get)
console.log(weakMap.get(user)); // "some metadata"
// 키 존재 여부 확인 (has)
console.log(weakMap.has(user)); // true
// user 객체를 참조하는 곳이 더 이상 없도록 null을 할당
user = null;
// 이 시점 이후, 가비지 컬렉터가 동작하면
// 'user' 객체는 메모리에서 제거되고,
// weakMap에서도 해당 키-값 쌍이 자동으로 사라집니다.
// (정확한 시점은 예측할 수 없습니다.)
</script>
1. 아톰과 실제 상태 값의 분리
Jotai에서 만드는 atom 객체 자체는 상태 값이 아니라, 상태를 가리키는 key와 같다. 실제 상태 값, 구독자 목록 등은 Jotai 내부의 별도 저장소에서 보관된다. --> WeakMap이 이 저장소 역할을 한다!
key: atom 객체
value: 해당 atom의 실제 상태 값(value). 이 atom에 의존하는 다른 atom 목록(dependents)
2. 자동 메모리 관리(가비지 컬렉션)
