WeakMap 오브젝트 -ECMAScript
WeakMap 오브젝트
- 개요
- GC(Garbage Collection)
- new WeakMap 인스턴스 생성
- set(): key, value 설정
- get(): key가 같은 value 반환
- has(): key 존재 여부
- delete(): 엘리먼트 삭제
- 개요
개요
WeakMap는 약한(weak) Map 오브젝트 입니다.Map 오브젝트와 작성 방법과 형태는 같지만, 약한 점이 있습니다.
WeakMap오브젝트는key에Object만 작성할 수 있으며string,numbers,symbol등의 (원시 데이터형)은 허용되지 않습니다.
value는 타입에 제한이 없습니다.
key에 오브젝트만 지정할 수 있는 것이 중요하며, 그 이유를 이해하는 것이WeakMap오브젝트의 사용 핵심입니다.- ex) let music = {title: “음악”} 코드를 실행하면 music 변수에 Object 오브젝트를 생성하여 할당합니다.
다시 music 변수에 {singer: “가수”}를 할당하면 {title: “음악”}을 사용할 수 없게 됩니다.
당연한 예시지만, 이로 인해 발생하는 문제를 해결하기 위한 것이 WeakMap 오브젝트의 목적입니다.
- ex) let music = {title: “음악”} 코드를 실행하면 music 변수에 Object 오브젝트를 생성하여 할당합니다.
GC(Garbage Collection)
1 | 1. let music = {title: "음악"}; |
- 생성된
Object 오브젝트가 메모리에 설정되며, 메모리 주소가music 변수에 할당됩니다.music을 전개하면{title: “음악”}이 전개됩니다.music을 전개하다는 것은music변수에설정된 메모리 주소의 오브젝트를 전개하는 것입니다.
music = {singer: “가수”}도Object 오브젝트를 생성하여 메모리에 설정합니다. 생성한 Object 오브젝트를music 변수에 할당하므로music 변수의 메모리 주소가 바뀌게 됩니다.
즉,{title: “음악”}을 사용할 수 없게 됩니다.
이때 엔진은 사용하지 않는 {title: “음악”}을 메모리에서 지웁니다.
이를 GC(Garbage Collection)라고 하고, GC를 수행하는 것을 Garbage Collector라고 합니다.
GC를 하지 않으면 사용하지 않는 메모리가 쌓이게 됩니다. 즉 메모리 릭(Memory Leak)이 발생합니다.
GC가 사용하지 않게 된 오브젝트를 메모리에서 지우면, WeakMap 인스턴스의 key에서 오브젝트를 참조할 수 없게됩니다. 메모리에 존재하지 않는 오브젝트를 참조하는 것은 문제가 됩니다. 이때, 엔진이 WeakMap 인스턴스의 key 와 value를 삭제합니다. 개발자 코드로 삭제하지 않아도 됩니다. 이런 점을 반영한 것이 WeakMap 오브젝트입니다.
WeakMap 오브젝트에서 제공하는 메서드는 간단합니다.set(), get(), has(), delete()만 있습니다. WeakMap 인스턴스에 [key, value]를 CRUD(Create, Read, Update, Delete)하기 위한 기본적인 메서드만 있습니다.WeakMap 인스턴스는 열거할 수 없습니다. 그러므로 forEach(), entries() 메서드가 없습니다.
Map 오브젝트는 size 프로퍼티가 있어 현재의 [key, value] 수를 알 수 있으나, WeakMap 오브젝트는 size 프로퍼티가 없어서 현재의 [key, value] 수를 알 수 없습니다. length 프로퍼티도 개발자 도구에서는 표시되나 실제로 사용하면 undefined를 반환합니다.
new WeakMap 인스턴스 생성
WeakMap 인스턴스를 생성하여 반환합니다.
new WeakMap()
선택적 파라미터
Object, 이터러블 오브젝트안에 작성 [key, value] 형태반환
생성한 WeakMap 인스턴스
1 | const emptyWeakMap = new WeakMap(); |
WeakMap()에 파라미터를 작성하지 않아도WeakMap인스턴스를 생성할 수 있습니다.
이는 상황에 따라 엘리먼트를 추가하려는 의도입니다.
WeakMap()파라미터에 이터러블 오브젝트를 작성하고 그 안에[key, value]형태로 작성합니다.key에 오브젝트 이름을 지정하고value에 값을 작성합니다.key인 오브젝트 자체에 프로퍼티가 있으므로value는 오브젝트에 대한주석(설명)이라고 볼 수 있습니다.
set(): key, value 설정
WeakMap 인스턴스에 key 와 value를 설정합니다.
WeakMap.prototype.set()
파라미터
- Object (key, Object/Function 등의 오브젝트)
- any (value)
반환
key, value가 추가된 WeakMap 인스턴스
첫 번째 파라미터에 key로 설정될 Object, Function과 같은 오브젝트를 지정합니다.string, numbers, boolean, null, undefined, symbol을 지정하면 에러가 발생합니다.
두 번째 파라미터에 임의의 값을 작성합니다.
1 | ; |
- 위 코드는 상황에 따라 실행 결과가 다르게 출력될 수 있습니다.
개발자 도구에서Sources로 들어가.js파일을 선택해 소스 코드를 화면에 표시하고
F5를 눌러 새로고침 합니다. 소스 코드 두 번째 줄에debugger를 작성했으므로 이 앞에서 멈추게 됩니다.debugger로 멈춘 시점에서 한 줄씩 소스 코드를 이동하면, 실행 결과의 1번 형태로 출력되지 않고,“WeakMap {}”형태가 출력될 수 있습니다. 이는 소스 코드를 한 줄씩 따라 가는 동안GC가 실행되어WeakMap인스턴스의[key, value]를 삭제하기 때문입니다.
(function(){코드});형태는 자동으로 함수가 실행됩니다.
함수를 저장하지 않고 한 번만 사용하려는 것이 목적입니다. 함수 실행이 끝나 함수를 빠져나오면 함수에서 선언한 변수가 저장되지 않으므로 다시 사용할 수 없습니다. 이렇게 사용하지 않게 된 것을Garbage Collector가 메모리에서 삭제합니다.newWeakMap.set(obj, “GC”)을 실행하면,obj오브젝트를 참조하는 메모리 주소가newWeakMap인스턴스의key에 설정됩니다. 함수 실행이 끝나 함수를 빠져나오면 함수블록의obj변수가 메모리에서 삭제됩니다.따라서
newWeakMap인스턴스의key에서obj오브젝트를 참조할 수 없게 됩니다.
이때,obj변수에서 참조하는{item: “weakmap”}이 메모리에서 지워지면newWeakMap인스턴스의[key, value]를 삭제합니다. 이것이WeakMap오브젝트의 목적입니다.
- 위의 1번 코드와 같은 형식이며
WeakMap이 아닌Map을 사용한 것이 다릅니다.
함수를 빠져나오면obj오브젝트를 참조하는Map인스턴스[key, value]를 삭제하지 않고 유지합니다.
이점이WeakMap과Map의 차이입니다.
- 1초 후에
setTimeout콜백 함수를 실행하게 됩니다. 1초 간격을 둔 것은GC의 실행 여부에 따른 상태를 출력하기 위해서 입니다.
console.log()로newWeakMap을 찍으면 두 가지 형태로 출력될 수 있습니다.newWeakMap인스턴스의key로 등록한 오브젝트가 메모리에서 삭제되면newWeakMap인스턴스의[key, value]가 삭제되므로 빈 Object 오브젝트 {}가 출력됩니다. 메모리에서 삭제되지 않은 상태라면,newWeakMap인스턴스에[key, value]가 남아 있으므로1: WeakMap {Object {item: “weakmap”} => “GC”}형태로 출력됩니다.
newMap인스턴스는GC의 영향을 받지 않으므로 항상Map {Object {item: “map”} => “keep”}형태로 출력됩니다.
1 | const newWeakMap = new WeakMap(); |
sportsObj변수에Object오브젝트를 생성하여 할당하고,set( )의 첫 번째 파라미터에sportsObj를 지정하여 추가합니다.
- 새로운
Object오브젝트를 생성하여sportsObj변수에 할당하므로sportsObj가 참조하는메모리 주소가 변경됩니다.newWeakMap인스턴스에key로 설정된sportsObj가 참조하는Object오브젝트는GC대상이 됩니다.
set( )의 첫 번째 파라미터에sportsObj를 지정하여 설정합니다.newWeakMap인스턴스에sportsObj가 있지만,sportsObj가 참조하는 메모리 주소가 다르므로 추가됩니다. 따라서newWeakMap인스턴스에는sportsObj가 참조하는Object오브젝트가 두 개 존재하게 됩니다. 개발자 도구에서 소스 코드에 중단점(Break Point)를 걸어newWeakMap인스턴스를 펼치면 두 개의Object오브젝트가 표시됩니다.
1 | const newWeakMap = new WeakMap(); |
function오브젝트를 생성하여변수 fn에 할당한 후,set()에서key로 지정하여newWeakMap에 추가합니다.function오브젝트도 오브젝트이므로WeakMap인스턴스에 설정할 수 있습니다.
set( )의 첫 번째 파라미터에fn을 지정하여newWeakMap인스턴스에 설정합니다.fn이 참조하는메모리 주소가 같으므로 추가하지 않고 두 번째 파라미터 값으로value를 변경합니다.newWeakMap인스턴스에[key, value]가 하나만 존재합니다.
get(): key가 같은 value 반환
WeakMap 인스턴스에서 지정한 key의 value를 반환합니다.
WeakMap.prototype.get()
파라미터
WeakMap 인스턴스의 key와 비교할 오브젝트를 지정합니다.반환 값
key가 존재하면 value를 반환하고, 존재하지 않으면 undefined를 반환합니다.
1 | const newWeakMap = new WeakMap(); |
obj변수에 Object 오브젝트를 생성하여 할당하고, 이를key로 하여newWeakMap인스턴스에 추가합니다.value값은 “오브젝트”입니다.get()파라미터에 오브젝트를 지정합니다.newWeakMap인스턴스에 파라미터로 지정한obj오브젝트가 존재하므로[key, value]에서value를 반환합니다.
has(): key 존재 여부
WeakMap 인스턴스에서 key 존재 여부를 반환합니다. true/false
WeakMap.prototype.has()
파라미터에 WeakMap 인스턴스의 key와 비교할 오브젝트를 지정합니다. 오브젝트가 존재하면 true, 아니면 false를 반환합니다.
1 | const newWeakMap = new WeakMap(); |
- Object 오브젝트를 생성하여 obj 변수에 할당하고, 이를 key로 하여 newWeakMap 인스턴스에 설정합니다. value값은 “오브젝트”입니다.
newWeakMap 인스턴스에 has()파라미터에 지정한 obj 오브젝트가 존재하므로 true가 출력됩니다.
delete(): 엘리먼트 삭제
WeakMap 인스턴스에서 key가 같은 엘리먼트를 삭제합니다.
WeakMap.prototype.delete()
파라미터의 WeakMap 인스턴스의 key와 비교할 오브젝트를 지정합니다. key가 존재하면 [key, value]를 삭제하고 true를 반환합니다. 존재하지 않으면 false를 반환합니다.
1 | const newWeakMap = new WeakMap(); |
Object 오브젝트를 생성하여 obj 변수에 할당하고, 이를 key로 하여 newWeakMap에 추가한 상태에서 위 코드를 실행합니다. delete() 파라미터에 key로 등록된 obj 오브젝트를 지정했으므로 [key, value]가 삭제됩니다. 또한, 삭제에 성공했으므로 true를 반환합니다. newWeakMap 인스턴스에서 삭제하는 것이지 obj에서 참조하는 메모리의 Object 오브젝트{}가 삭제되는 것은 아닙니다.