WeakMap은 object만 key로 사용 가능
Map에서 key로 참조한 object를 삭제하면
let sports = {like: "축구"};
const obj = new Map([
[sports, "like:축구"]
]);
sports = {like: "농구"};
WeakMap의 object를 GC가 지움
WeakMap 오브젝트 메소드
WeakMap entry의 열거 불가
이터레이션 불가
WeakMap 인스턴스 생성, 반환
파라미터 작성
const empty = new WeakMap();
const sports = {};
const obj = new WeakMap([
[sports, "sports 오브젝트"]
]);
log(typeof obj);
// object
const map = Map;
const weakmap = WeakMap;
/*
1. map과 weakmap이 구조에서 크게 다르지 않지만
2. Map 오브젝트에 Symbol(Symbol, species)가 있지만 WeakMap 오브젝트에는 없음
3. map.prototype에 Symbol.iterator가 있지만 weakmap.prototype에는 Symbol.iterator가 없음
4. map.prototype에는 forEach()가 있지만 weakmap.prototype에는 forEach()가 있음
*/
const sports = {};
const obj = new WeakMap([
[sports, "종목"]
]);
/*
1. 오른쪽의 obj를 펼치면 [[Entries]]가 있음. 이것은 엔진에서 설정하는 것을 뜻함.
2. [[Entries]]를 펼치면 0: {Object => "종목"} 형태
- [Object, "종목"] 형태로 작성한 것을 인덱스를 부여하여 배열로 만들고, 엘리먼트에 {Object: "종목"} 형태로 변환함
3. Map 인스턴스와 구조가 같음
*/
const fn = () => {};
const obj = new WeakMap([
[fn, "함수"]
]);
log(obj.get(fn));
// 함수
const fn = function(){};
const obj = new WeakMap([
[fn, "함수"]
]);
log(obj.get(fn));
obj.set(fn, "함수 변경");
log(obj.get(fn));
// 함수
// 함수 변경
첫 번째 파라미터에 key로 사용할 오브젝트 작성
두 번째 파라미터는 값
const obj = {};
const weakobj = new WeakMap([
[obj, "오브젝트"]
]);
log(weakObj.has(obj));
// true
const fn = function(){};
const obj = new WeakMap([
[fn, "함수"]
]);
log(obj.delete(fn));
log(obj.has(fn));
// true
// false
let obj = new WeakMap();
let sports = () => {point: 1};
obj.set(sports, "변경전");
sports = () => {point: 2};
obj.set(sports, "변경후");
let sports = () => {point: 1}; obj.set(sports, "변경전");
sports = () => {point: 2};
obj.set(sports, "변경후");
WeakMap 인스턴스의 GC 상태
// WeakMap 인스턴스의 GC 상태
let obj = new WeakMap();
let sports = () => {point: 1};
obj.set(sports, "변경전");
/*
1. 아래에서 sports 변수에 {point: 2}를 할당하므로 sports가 참조하는 오브젝트가 바뀜
*/
sports = () => {point: 2};
obj.set(sports, "변경후");
/*
1. obj의 [[Entries]]를 펼치면 0과 1이 있음
- 변수값은 바뀌어 하나이지만 WeakMap 인스턴스에는 두 개가 있음
2. {point: 1}과 {point: 2}의 메모리 주소가 다르며 sports는 사람이 보는 것으로 WeakMap은 값인 메모리 주소가 다르므로 각각 저장함
3. 그래서 sports로 저장하지 않고 인덱스를 부여하여 저장하는 것
- 엔진은 인덱스가 key이며 sports는 프로퍼티 value에서 프로퍼티 키
*/
setTimeout(function(){
console.log(obj.get(sports));
}, 2000);
/*
1. {point: 1}의 sports를 사용할 수 없으므로 GC가 {point: 1}의 sports를 메모리에서 지움. 또한 obj의 "변경전"도 삭제
2. 인덱스 1번에 0이 됨
3. Map 오브젝트에서 entry를 삭제해도 인덱스를 정리
*/
참조하는 object를 삭제하면
Map과 WeakMap 차이
// Map과 WeakMap 차이
let mapObj = new Map();
(function(){
const obj = {key: "value"};
mapObj.set(obj, "Map");
}());
let weakObj = new WeakMap();
(function(){
const obj = {key: "value"};
weakObj.set(obj, "WeakMap");
}());
let mapObj = new Map(); (function(){...}());
const weakObj = new WeakMap(); (function(){...}());
// Map과 WeakMap 차이
let mapObj = new Map();
(function(){
const obj = {key: "value"};
mapObj.set(obj, "Map");
}());
/*
1. mapObj를 펼치면 entry가 있음
*/
let weakObj = new WeakMap();
(function(){
const obj = {key: "value"};
weakObj.set(obj, "WeakMap");
}());
/*
1. weakObj를 펼치면 entry가 있음
*/
setTimeOut(function(){
console.log(weakObj);
console.log(mapObj);
/*
1. mapObj에는 entry가 있지만 weakObj에는 없음
2. GC가 obj를 지우면서 WeakMap의 obj도 지우기 때문
*/
}, 1000);