[자바스크립트 ES6+ 기본] 22. WeakMap 오브젝트
WeakMap 오브젝트
-
WeakMap은 object만 key로 사용 가능
- number 등의 프리미티브 타입 사용 불가
- value는 제한 없음
-
Map에서 key로 참조한 object를 삭제하면
- object를 사용할 수 없게 되지만
- Map에 object가 남음
- 메모리 릭(memory leak) 발생
let sports = {like: "축구"};
const obj = new Map([
[sports, "like:축구"]
]);
sports = {like: "농구"};
-
WeakMap의 object를 GC가 지움
- GC: Garbage Collection
- 그래서 (약한, 부서지기 쉬운) WeakMap?
-
WeakMap 오브젝트 메소드
- set(), get(), has(), delete()
- CRUD와 관련된 메소드만 있음
-
WeakMap entry의 열거 불가
-
이터레이션 불가
new WeakMap()
-
WeakMap 인스턴스 생성, 반환
-
파라미터 작성
- 대괄호[] 안에 이터러블 오브젝트 작성
const empty = new WeakMap();
const sports = {};
const obj = new WeakMap([
[sports, "sports 오브젝트"]
]);
log(typeof obj);
// object
- WeakMap 오브젝트 구조
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 인스턴스와 구조가 같음
*/
WeakMap 오브젝트 메소드
get()
- WeakMap 인스턴스에서
- key 값이 같은 value 반환
- 존재하지 않으면 undefined 반환
const fn = () => {};
const obj = new WeakMap([
[fn, "함수"]
]);
log(obj.get(fn));
// 함수
set()
- WeakMap 인스턴스에 key, value 설정
const fn = function(){};
const obj = new WeakMap([
[fn, "함수"]
]);
log(obj.get(fn));
obj.set(fn, "함수 변경");
log(obj.get(fn));
// 함수
// 함수 변경
-
첫 번째 파라미터에 key로 사용할 오브젝트 작성
- string과 같은 프리미티브 값 사용 불가
-
두 번째 파라미터는 값
- 첫 번째 파라미터의 오브젝트에 대한 값?
- 오브젝트 구분 등의 용도. 오브젝트에 따라 연동하는 함수 등록
has()
- WeakMap 인스턴스에서
- key의 존재 여부 반환
- 존재하면 true, 아니면 false 반환
const obj = {};
const weakobj = new WeakMap([
[obj, "오브젝트"]
]);
log(weakObj.has(obj));
// true
delete()
- WeakMap 인스턴스에서
- key와 일치하는 entry 삭제
- 삭제를 성공하면 true 반환
- 삭제를 실패하면 false 반환
const fn = function(){};
const obj = new WeakMap([
[fn, "함수"]
]);
log(obj.delete(fn));
log(obj.has(fn));
// true
// false
가비지 컬렉션 처리
- 참조하는 object가 바뀌면
- 참조했던 오브젝트가 가비지 컬렉션 처리됨
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에 Function 오브젝트를 할당하고
- 이것을 WeakMap 인스턴스에 key로 설정
-
sports = () => {point: 2};
- 새로운 함수를 생성하여 할당
- 바로 위의 sports가 참조하는 메모리 주소가 바뀜
- sports가 참조하는 메모리 주소가 바뀌면 앞의 sports가 참조했던 오브젝트를 호출할 수 없게 됨
- 이렇게 사용할 수 없게 된 {point: 1} 오브젝트는 GC 대상이 됨
- 엔진이 주기적으로 GC 처리를 함
-
obj.set(sports, "변경후");
- sports를 key로 하여 WeakMap에 설정
- 앞에서 sports를 key로 하여 설정했으며 여기서도 sports를 key로 하여 설정하므로 값이 대체되어야 하지만
- 두 개의 sports가 참조하는 주소가 다르므로 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를 삭제해도 인덱스를 정리
*/
Map과 WeakMap 차이
-
참조하는 object를 삭제하면
- Map은 그대로 갖고 있지만
- WeakMap은 GC 처리로 삭제됨
-
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(){...}());
- 즉시 실행 함수는 일회용으로 변수를 저장하지 않을 때 사용
- 함수가 끝나면 obj 변수를 GC가 메모리에서 지움
- Map은 obj 변수가 지워지더라도 Map에 설정된 obj를 지우지 않고 유지
-
const weakObj = new WeakMap(); (function(){...}());
- 앞의 실행 환경과 같음
- 다만, Map이 아닌 WeakMap에 저장
- WeakMap은 obj 변수가 삭제되면 WeakMap에 설정된 obj를 삭제함
// 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);
Author And Source
이 문제에 관하여([자바스크립트 ES6+ 기본] 22. WeakMap 오브젝트), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@bbirong/자바스크립트-ES6-기본-22.-WeakMap-오브젝트
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
WeakMap은 object만 key로 사용 가능
- number 등의 프리미티브 타입 사용 불가
- value는 제한 없음
Map에서 key로 참조한 object를 삭제하면
- object를 사용할 수 없게 되지만
- Map에 object가 남음
- 메모리 릭(memory leak) 발생
let sports = {like: "축구"};
const obj = new Map([
[sports, "like:축구"]
]);
sports = {like: "농구"};
WeakMap의 object를 GC가 지움
- GC: Garbage Collection
- 그래서 (약한, 부서지기 쉬운) WeakMap?
WeakMap 오브젝트 메소드
- set(), get(), has(), delete()
- CRUD와 관련된 메소드만 있음
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 인스턴스와 구조가 같음
*/
- key 값이 같은 value 반환
- 존재하지 않으면 undefined 반환
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로 사용할 오브젝트 작성
- string과 같은 프리미티브 값 사용 불가
두 번째 파라미터는 값
- 첫 번째 파라미터의 오브젝트에 대한 값?
- 오브젝트 구분 등의 용도. 오브젝트에 따라 연동하는 함수 등록
- key의 존재 여부 반환
- 존재하면 true, 아니면 false 반환
const obj = {};
const weakobj = new WeakMap([
[obj, "오브젝트"]
]);
log(weakObj.has(obj));
// true
- key와 일치하는 entry 삭제
- 삭제를 성공하면 true 반환
- 삭제를 실패하면 false 반환
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에 Function 오브젝트를 할당하고
- 이것을 WeakMap 인스턴스에 key로 설정
sports = () => {point: 2};
- 새로운 함수를 생성하여 할당
- 바로 위의 sports가 참조하는 메모리 주소가 바뀜
- sports가 참조하는 메모리 주소가 바뀌면 앞의 sports가 참조했던 오브젝트를 호출할 수 없게 됨
- 이렇게 사용할 수 없게 된 {point: 1} 오브젝트는 GC 대상이 됨
- 엔진이 주기적으로 GC 처리를 함
obj.set(sports, "변경후");
- sports를 key로 하여 WeakMap에 설정
- 앞에서 sports를 key로 하여 설정했으며 여기서도 sports를 key로 하여 설정하므로 값이 대체되어야 하지만
- 두 개의 sports가 참조하는 주소가 다르므로 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은 GC 처리로 삭제됨
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(){...}());
- 즉시 실행 함수는 일회용으로 변수를 저장하지 않을 때 사용
- 함수가 끝나면 obj 변수를 GC가 메모리에서 지움
- Map은 obj 변수가 지워지더라도 Map에 설정된 obj를 지우지 않고 유지
const weakObj = new WeakMap(); (function(){...}());
- 앞의 실행 환경과 같음
- 다만, Map이 아닌 WeakMap에 저장
- WeakMap은 obj 변수가 삭제되면 WeakMap에 설정된 obj를 삭제함
// 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);
Author And Source
이 문제에 관하여([자바스크립트 ES6+ 기본] 22. WeakMap 오브젝트), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@bbirong/자바스크립트-ES6-기본-22.-WeakMap-오브젝트저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)