ES6 Map과 WeakMap의 차이점은 무엇입니까?
찾는 이 와 이 이지도와 WeakMaps 사이의 유일한 차이처럼 보인다 MDN 페이지 것은 WeakMaps에 대한 누락 "크기"속성입니다. 그러나 이것이 사실입니까? 그들 사이의 차이점은 무엇입니까?
에서 매우 같은 페이지, 섹션 " 왜 약한 지도? " :
숙련 된 JavaScript 프로그래머는이 API가 4 개의 API 메서드가 공유하는 두 개의 배열 (키용 하나, 값용 하나)을 사용하여 JavaScript에서 구현 될 수 있음을 알 수 있습니다. 이러한 구현에는 두 가지 주요 불편이 있습니다. 첫 번째는 O (n) 검색입니다 (n은 맵의 키 수). 두 번째는 메모리 누수 문제입니다. 수동으로 작성된 맵을 사용하면 키 배열이 키 개체에 대한 참조를 유지하여 가비지 수집을 방지합니다. 네이티브 WeakMaps에서 키 객체에 대한 참조는 "약하게" 유지 됩니다. 즉, 객체에 대한 다른 참조가 없을 경우 가비지 수집을 방지하지 않습니다.
참조가 약하기 때문에 WeakMap 키는 열거 할 수 없습니다 (즉, 키 목록을 제공하는 메서드가 없습니다). 그럴 경우 목록은 가비지 수집 상태에 따라 달라지며 비결 정성을 도입합니다.
[그것도 size
재산 이없는 이유입니다 ]
키 목록을 갖고 싶다면 직접 유지해야합니다. 약한 참조를 사용하지 않고 열거 할 수있는 간단한 세트와 맵을 도입하는 것을 목표로 하는 ECMAScript 제안 도 있습니다.
-이 될 것이다 "정상" Map
의 . MDN에 언급,하지만하지 조화를 제안 , 그 또한 가지고 items
, keys
및 values
생성 방법과 구현 Iterator
인터페이스를 .
키 / 값이 참조하는 객체가 삭제되면 둘 다 다르게 작동합니다. 아래 예제 코드를 살펴 보겠습니다.
var map = new Map();
var weakmap = new WeakMap();
(function(){
var a = {x: 12};
var b = {y: 12};
map.set(a, 1);
weakmap.set(b, 2);
})()
위의 인생은 우리가 참조 할 수있는 방법은 없습니다 실행 {x: 12}
하고 {y: 12}
더 이상은. 가비지 수집기는 계속해서 "WeakMap"에서 키 b 포인터를 삭제 {y: 12}
하고 메모리 에서도 제거합니다 . 그러나 "Map"의 경우 가비지 수집기는 "Map"에서 포인터를 제거하지 않고 {x: 12}
메모리 에서도 제거하지 않습니다 .
요약 : WeakMap을 사용하면 가비지 수집기가 작업을 수행 할 수 있지만 Map은 수행 할 수 없습니다.
참조 : http://qnimate.com/difference-between-map-and-weakmap-in-javascript/
아마도 다음 설명은 누군가에게 더 명확 할 것입니다.
var k1 = {a: 1};
var k2 = {b: 2};
var map = new Map();
var wm = new WeakMap();
map.set(k1, 'k1');
wm.set(k2, 'k2');
k1 = null;
map.forEach(function (val, key) {
console.log(key, val); // k1 {a: 1}
});
k2 = null;
wm.get(k2); // undefined
As you see, after removing k1
key from the memory we can still access it inside the map. At the same time removing k2
key of WeakMap removes it from wm
as well by reference.
That's why WeakMap hasn't enumerable methods like forEach, because there is no such thing as list of WeakMap keys, they are just references to another objects.
Another difference (source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap):
Keys of WeakMaps are of the type Object only. Primitive data types as keys are not allowed (e.g. a Symbol can't be a WeakMap key).
Nor can a string, number, or boolean be used as a WeakMap
key. A Map
can use primitive values for keys.
w = new WeakMap;
w.set('a', 'b'); // Uncaught TypeError: Invalid value used as weak map key
m = new Map
m.set('a', 'b'); // Works
WeapMap in javascript does not hold any keys or values, it just manipulate key value using a unique id and define property to key object.
because it define property to key
by method Object.definePropert()
, key must not be primitive type.
and also because WeapMap does not contain actually key value pairs, we cannot get length property of weakmap.
and also manipulated value is assigned back to key, garbage collector easily can collect key if it in no use.
Sample code for implementation.
if(typeof WeapMap != undefined){
return;
}
(function(){
var WeapMap = function(){
this.__id = '__weakmap__';
}
weakmap.set = function(key,value){
var pVal = key[this.__id];
if(pVal && pVal[0] == key){
pVal[1]=value;
}else{
Object.defineProperty(key, this.__id, {value:[key,value]});
return this;
}
}
window.WeakMap = WeakMap;
})();
reference of implementation
WeakMap
keys must be objects, not primitive values.
let weakMap = new WeakMap();
let obj = {};
weakMap.set(obj, "ok"); // works fine (object key)
// can't use a string as the key
weakMap.set("test", "Not ok"); // Error, because "test" is not an object
Why????
Let's see below example.
let user = { name: "User" };
let map = new Map();
map.set(user, "...");
user = null; // overwrite the reference
// 'user' is stored inside the map,
// We can get it by using map.keys()
If we use an object as the key in a regular
Map
, then while theMap
exists, that object exists as well. It occupies memory and may not be garbage collected.
WeakMap
is fundamentally different in this aspect. It doesn’t prevent garbage-collection of key objects.
let user = { name: "User" };
let weakMap = new WeakMap();
weakMap.set(user, "...");
user = null; // overwrite the reference
// 'user' is removed from memory!
if we use an object as the key in it, and there are no other references to that object – it will be removed from memory (and from the map) automatically.
WeakMap
does not support iteration and methods keys(), values(), entries(), so there’s no way to get all keys or values from it.
WeakMap has only the following methods:
- weakMap.get(key)
- weakMap.set(key, value)
- weakMap.delete(key)
- weakMap.has(key)
That is obvious as if an object has lost all other references (like 'user' in the code above), then it is to be garbage-collected automatically. But technically it’s not exactly specified when the cleanup happens.
The JavaScript engine decides that. It may choose to perform the memory cleanup immediately or to wait and do the cleaning later when more deletions happen. So, technically the current element count of a WeakMap
is not known. The engine may have cleaned it up or not or did it partially. For that reason, methods that access all keys/values are not supported.
Note:- The main area of application for WeakMap is an additional data storage. Like caching an object until that object gets garbage collected.
참고URL : https://stackoverflow.com/questions/15604168/whats-the-difference-between-es6-map-and-weakmap
'developer tip' 카테고리의 다른 글
Integer.parseInt ()를 캡슐화하는 좋은 방법 (0) | 2020.09.20 |
---|---|
jquery [duplicate]를 사용하여 텍스트로 드롭 다운 값 설정 (0) | 2020.09.20 |
PowerShell에서 경로를 정규화하는 방법은 무엇입니까? (0) | 2020.09.20 |
TypeScript에서 json 파일 가져 오기 (0) | 2020.09.20 |
신속한 변환 범위 (0) | 2020.09.20 |