ES6 WeakMap의 실제 용도는 무엇입니까?


397

WeakMapECMAScript 6에 도입 된 데이터 구조 의 실제 용도는 무엇입니까 ?

약한 맵의 키가 약한 맵에 삽입 된 값 것을 보장 대응하는 값에 강한 기준을 작성하기 때문에 않을 만큼의 키가 아직 살아로서 사라질,이 메모 테이블을 사용할 수없는, 캐시 또는 일반적으로 약한 참조, 약한 값을 가진 맵 등을 사용하는 것.

이것은 나에게 보인다 :

weakmap.set(key, value);

... 이것에 대한 원형 교차로입니다.

key.value = value;

어떤 구체적인 사용 사례가 누락 되었습니까?




35
실제 사용 사례 : DOM 노드에 대한 사용자 정의 데이터를 저장하십시오.
Felix Kling

약한 참조에 대해 언급 한 모든 사용 사례도 매우 중요합니다. 비결정론을 도입하기 때문에 언어에 추가하기가 훨씬 어렵습니다. Mark Miller와 다른 사람들은 약한 참고 문헌에 대해 많은 노력을 기울였으며 결국에는 나올 것이라고 생각 합니다. 결국
Benjamin Gruenbaum

2
WeakMaps는 메모리 누수를 감지하는 데 사용할 수 있습니다. stevehanov.ca/blog/?id=148
TheWebalyst

답변:


513

근본적으로

WeakMaps는 가비지 수집을 방해하지 않고 외부에서 객체를 확장하는 방법을 제공합니다. 개체를 확장하려고하지만 봉인되어 있거나 외부 소스에서 개체를 확장 할 수 없을 때마다 WeakMap을 적용 할 수 있습니다.

WeakMap은지도 (사전)이다 키가 받는 모든 참조 경우입니다 - 약한 키가 손실되고 값의 참조가없는 - 값이 쓰레기 수집 할 수 있습니다가. 먼저 예제를 통해 이것을 보여주고 약간 설명하고 마침내 실제 사용으로 마무리합시다.

특정 객체를 제공하는 API를 사용한다고 가정 해 보겠습니다.

var obj = getObjectFromLibrary();

이제 객체를 사용하는 메소드가 있습니다.

function useObj(obj){
   doSomethingWith(obj);
}

특정 객체로 메소드가 몇 번이나 호출되었는지 추적하고 N 번 이상 발생하면보고하고 싶습니다. 순진하게도 맵을 사용하려고 생각합니다.

var map = new Map(); // maps can have object keys
function useObj(obj){
    doSomethingWith(obj);
    var called = map.get(obj) || 0;
    called++; // called one more time
    if(called > 10) report(); // Report called more than 10 times
    map.set(obj, called);
}

이것은 작동하지만 메모리 누수가 있습니다. 이제 라이브러리 객체가 가비지 수집되지 않도록하는 함수에 전달 된 모든 단일 라이브러리 객체를 추적합니다. 대신에-를 사용할 수 있습니다 WeakMap:

var map = new WeakMap(); // create a weak map
function useObj(obj){
    doSomethingWith(obj);
    var called = map.get(obj) || 0;
    called++; // called one more time
    if(called > 10) report(); // Report called more than 10 times
    map.set(obj, called);
}

그리고 메모리 누수가 사라졌습니다.

사용 사례

그렇지 않으면 메모리 누수를 유발하고에 의해 활성화되는 일부 사용 사례 WeakMap는 다음과 같습니다.

  • 특정 개체에 대한 개인 정보를 유지하고지도를 참조하여 사람들에게만 액세스 할 수 있습니다. 개인 기호 제안과 함께 좀 더 임시 접근 방식이 제공되지만 지금부터 오랜 시간이 걸렸습니다.
  • 라이브러리 객체를 변경하거나 오버 헤드를 발생시키지 않고 라이브러리 객체에 대한 데이터를 유지합니다.
  • 숨겨진 유형의 클래스에 문제가 발생하지 않도록 유형의 많은 오브젝트가있는 작은 오브젝트 세트에 대한 데이터 유지 JS 엔진은 동일한 유형의 오브젝트에 사용합니다.
  • 브라우저에서 DOM 노드와 같은 호스트 객체에 대한 데이터 유지
  • 외부에서 객체에 기능 추가 (다른 답변의 이벤트 이미 터 예제와 같이).

실제 사용을 보자

외부에서 물체를 확장하는 데 사용할 수 있습니다. Node.js의 실제 세계에서 실제적인 (적응 된 일종의 실제-포인트를 만들기 위해) 예를 들어 봅시다.

Node.js이고 Promise객체 가 있다고 가정 해 봅시다. 이제는 현재 거부 된 모든 약속을 추적하려고하지만 참조가없는 경우 가비지 수집을 피하고 싶지 는 않습니다 .

지금, 당신은 하지 않는 분명한 이유 네이티브 객체에 속성을 추가 할 - 당신이 붙어있어 수 있도록. 약속을 참조하면 가비지 수집이 발생할 수 없으므로 메모리 누수가 발생합니다. 참조를 유지하지 않으면 개별 약속에 대한 추가 정보를 저장할 수 없습니다. 약속의 ID 저장과 관련된 모든 체계는 본질적으로 약속의 참조가 필요함을 의미합니다.

약한지도 입력

WeakMaps는 가 약하다는 것을 의미합니다 . 약한 맵을 열거하거나 모든 값을 얻는 방법은 없습니다. 약한 맵에서 키를 기반으로 데이터를 저장할 수 있으며 키가 가비지 수집되는 시점도 값을 저장합니다.

이것은 약속이 주어지면 그것에 대한 상태를 저장할 수 있으며 객체는 여전히 가비지 수집 될 수 있음을 의미합니다. 나중에 개체에 대한 참조가 있으면 관련된 상태가 있는지 확인하고보고 할 수 있습니다.

이것은 Petka Antonov의 처리되지 않은 거부 후크다음 과 같이 구현하는 데 사용되었습니다 .

process.on('unhandledRejection', function(reason, p) {
    console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason);
    // application specific logging, throwing an error, or other logic here
});

약속에 대한 정보를지도에 보관하고 거부 된 약속이 처리 된시기를 알 수 있습니다.


8
여보세요! 예제 코드의 어느 부분이 메모리 누수를 일으키는 지 알려주시겠습니까?
ltamajs

15
@ ltamajs4 는 a 가 아닌 a useObj를 사용하는 예제 에서 전달 된 객체를 맵 키로 사용합니다. 객체는지도에서 제거되지 않습니다 (언제 언제해야할지 알지 못하므로) 항상 이에 대한 참조가 있으며 가비지 수집 될 수 없습니다. WeakMap 예제에서 객체에 대한 다른 모든 참조가 사라지는 즉시 객체를 객체에서 지울 수 있습니다 . 아직도 무슨 뜻인지 잘 모르겠다면 알려주세요MapWeakMapWeakMap
Benjamin Gruenbaum

@ Benjamin, 우리는 메모리에 민감한 캐시의 필요성과 data_object 튜플의 필요성을 구별해야합니다. 이 두 가지 요구 사항을 혼동하지 마십시오. 귀하의 called예를 더 나은 사용하여 작성 jsfiddle.net/f2efbm7z을 하며 약한지도의 사용을 설명하지 않습니다. 실제로, 총 6 가지 방법으로 작성하는 것이 더 좋으며 , 아래에 나열하겠습니다.
Pacerier

기본적으로 약한 맵의 목적은 메모리에 민감한 캐시입니다. 외부에서 객체를 확장하는 데 사용할 수 있지만, 이는 명백한 야만적 인 해킹이며 반드시 적절한 목적은 아닙니다 .
Pacerier

1
약속과 약속 / 처리 된 횟수 사이의 연결을 유지하려면 1) 기호를 사용하십시오. p[key_symbol] = data. 또는 2) 고유 한 명명; p.__key = data. 또는 3) 사적 범위; (()=>{let data; p.Key = _=>data=_;})(). 또는 4) 1 또는 2 또는 3의 프록시 또는 5) 1 또는 2 또는 3 으로 Promise 클래스 교체 / 확장 또는 6) 필요한 멤버의 튜플로 Promise 클래스를 교체 / 확장합니다. — 어쨌든 메모리에 민감한 캐시가 필요 하지 않으면 약한 맵이 필요 하지 않습니다 .
Pacerier

48

이 답변은 실제 시나리오에서 편향되어 사용할 수없는 것으로 보입니다. 그대로 읽어보고 실험 이외의 다른 옵션으로는 고려하지 마십시오.

유스 케이스는 청취자를위한 사전으로 사용하는 것일 수 있습니다. 동료가 있습니다. 모든 청취자가 이러한 방식으로 직접 타겟팅되므로 매우 유용합니다. 안녕 listener.on.

그러나보다 추상적 인 관점에서 볼 WeakMap때 기본적으로 모든 것에 대한 액세스를 비 물질화하는 것이 특히 강력합니다.이 구조의 특성에 의해 이미 암시되어 있으므로 멤버를 분리하기 위해 네임 스페이스가 필요하지 않습니다. 어색한 중복 객체 키를 교체하여 메모리를 크게 개선 할 수 있다고 확신합니다 (해체가 당신을 위해 일하더라도).


다음 내용을 읽기 전에

나는 지금 내 정확하게 문제와 같이 해결하는 가장 좋은 방법은 아닙니다 강조 실현 않는 벤자민 Gruenbaum는 ,이 문제가 정기적으로 해결 될 수 없었다 (P가 내 위에 이미 아니라면, 그의 대답을 체크 아웃) 지적을 Map하기 때문에, 유출되었을 것이므로 주된 장점은 WeakMap참조를 유지하지 않으면 가비지 수집을 방해하지 않는다는 것입니다.


여기 내 동료의 실제 코드는 (덕분에 공유)

여기 에 대한 전체 소스 는 위에서 설명한 청취자 관리에 관한 것입니다 ( 사양을 볼 수도 있습니다 )

var listenableMap = new WeakMap();


export function getListenable (object) {
    if (!listenableMap.has(object)) {
        listenableMap.set(object, {});
    }

    return listenableMap.get(object);
}


export function getListeners (object, identifier) {
    var listenable = getListenable(object);
    listenable[identifier] = listenable[identifier] || [];

    return listenable[identifier];
}


export function on (object, identifier, listener) {
    var listeners = getListeners(object, identifier);

    listeners.push(listener);
}


export function removeListener (object, identifier, listener) {
    var listeners = getListeners(object, identifier);

    var index = listeners.indexOf(listener);
    if(index !== -1) {
        listeners.splice(index, 1);
    }
}


export function emit (object, identifier, ...args) {
    var listeners = getListeners(object, identifier);

    for (var listener of listeners) {
        listener.apply(object, args);
    }
}

2
나는 당신이 이것을 어떻게 사용할 것인지 잘 모릅니다. 더 이상 참조하지 않을 경우 observable이 바인딩 된 이벤트와 함께 축소됩니다. 내가 가진 경향은 관찰자가 더 이상 참조되지 않을 때입니다. 여기의 해결책은 문제의 절반 만 해결했다고 생각합니다. WeakMap이 반복 가능하지 않기 때문에 관찰자 문제를 해결할 수 있다고 생각하지 않습니다.
jgmjgm 2016

1
이중 버퍼링 이벤트 리스너는 다른 언어에서는 빠를 수 있지만이 경우에는 보통 난해하고 느립니다. 저의 3 센트입니다.
잭 지핀

@axelduch,이 청취자 처리 신화는 자바 스크립트 커뮤니티 에까지 퍼져 40 개의 인기를 얻었습니다! 이 답변이 완전히 틀린 이유를 이해하려면 stackoverflow.com/a/156618/632951
Pacerier의

1
@Pacerier, 피드백에 대한 감사 답변을 업데이트
axelduch

1
@axelduch, 그래, 거기에도 심판이 있습니다.
Pacerier

18

WeakMap 캡슐화 및 정보 숨기기에 적합

WeakMapES6 이상에서만 사용할 수 있습니다. A WeakMap는 키가 객체 여야하는 키 및 값 쌍의 모음입니다. 다음 예제에서는 WeakMap두 가지 항목으로를 만듭니다 .

var map = new WeakMap();
var pavloHero = {first: "Pavlo", last: "Hero"};
var gabrielFranco = {first: "Gabriel", last: "Franco"};
map.set(pavloHero, "This is Hero");
map.set(gabrielFranco, "This is Franco");
console.log(map.get(pavloHero));//This is Hero

우리는이 set()메소드를 사용하여 객체와 다른 아이템 (우리의 경우 문자열) 사이의 연관을 정의했습니다. 이 get()방법을 사용하여 객체와 관련된 항목을 검색했습니다. 의 흥미로운 측면은 WeakMap맵 내부의 키에 대한 약한 참조를 가지고 있다는 사실입니다. 약한 참조는 객체가 파괴되면 가비지 수집기가에서 전체 항목을 제거하여 WeakMap메모리를 비 웁니다.

var TheatreSeats = (function() {
  var priv = new WeakMap();
  var _ = function(instance) {
    return priv.get(instance);
  };

  return (function() {
      function TheatreSeatsConstructor() {
        var privateMembers = {
          seats: []
        };
        priv.set(this, privateMembers);
        this.maxSize = 10;
      }
      TheatreSeatsConstructor.prototype.placePerson = function(person) {
        _(this).seats.push(person);
      };
      TheatreSeatsConstructor.prototype.countOccupiedSeats = function() {
        return _(this).seats.length;
      };
      TheatreSeatsConstructor.prototype.isSoldOut = function() {
        return _(this).seats.length >= this.maxSize;
      };
      TheatreSeatsConstructor.prototype.countFreeSeats = function() {
        return this.maxSize - _(this).seats.length;
      };
      return TheatreSeatsConstructor;
    }());
})()

4
"캡슐화 및 정보 숨기기에 약한 맵이 작동합니다". 당신이 할 수 있다고해서 꼭 그래야하는 것은 아닙니다. Javascript에는 weakmap이 발명되기 전에도 캡슐화 및 정보 숨기기를 수행하는 기본 방법이 있습니다. 지금과 같이 말 그대로 6 가지 방법이 있습니다 . weakmap을 사용하여 캡슐화를 수행하는 것은 추악한 얼굴입니다.
Pacerier

12

𝗠𝗲𝘁𝗮𝗱𝗮𝘁𝗮

약한지도를 사용하면 가비지 수집을 방해하거나 동료를 화나게하지 않고도 DOM 요소에 대한 메타 데이터를 저장할 수 있습니다. 예를 들어, 웹 페이지의 모든 요소를 ​​숫자로 색인화하는 데 사용할 수 있습니다.

𝗪𝗶𝘁𝗵𝗼𝘂𝘁 𝗪𝗲𝗮𝗸𝗠𝗮𝗽𝘀 𝗼𝗿 𝗪𝗲𝗮𝗸𝗦𝗲𝘁𝘀 :

var elements = document.getElementsByTagName('*'),
  i = -1, len = elements.length;

while (++i !== len) {
  // Production code written this poorly makes me want to cry:
  elements[i].lookupindex = i;
  elements[i].elementref = [];
  elements[i].elementref.push( elements[(i * i) % len] );
}

// Then, you can access the lookupindex's
// For those of you new to javascirpt, I hope the comments below help explain 
// how the ternary operator (?:) works like an inline if-statement
document.write(document.body.lookupindex + '<br />' + (
    (document.body.elementref.indexOf(document.currentScript) !== -1)
    ? // if(document.body.elementref.indexOf(document.currentScript) !== -1){
    "true"
    : // } else {
    "false"
  )   // }
);

𝗨𝘀𝗶𝗻𝗴 𝗪𝗲𝗮𝗸𝗠𝗮𝗽𝘀 𝗮𝗻𝗱 𝗪𝗲𝗮𝗸𝗦𝗲𝘁𝘀 :

var DOMref = new WeakMap(),
  __DOMref_value = Array,
  __DOMref_lookupindex = 0,
  __DOMref_otherelement = 1,
  elements = document.getElementsByTagName('*'),
  i = -1, len = elements.length, cur;

while (++i !== len) {
  // Production code written this greatly makes me want to 😊:
  cur = DOMref.get(elements[i]);
  if (cur === undefined)
    DOMref.set(elements[i], cur = new __DOMref_value)

  cur[__DOMref_lookupindex] = i;
  cur[__DOMref_otherelement] = new WeakSet();
  cur[__DOMref_otherelement].add( elements[(i * i) % len] );
}

// Then, you can access the lookupindex's
cur = DOMref.get(document.body)
document.write(cur[__DOMref_lookupindex] + '<br />' + (
    cur[__DOMref_otherelement].has(document.currentScript)
    ? // if(cur[__DOMref_otherelement].has(document.currentScript)){
    "true"
    : // } else {
    "false"
  )   // }
);

𝗧𝗵𝗲 𝗗𝗶𝗳𝗳𝗲𝗿𝗲𝗻𝗰𝗲

weakmap 버전이 더 길다는 점을 제외하고는 차이가 무시할 만 할 수 있지만 위에 표시된 두 코드 조각 간에는 큰 차이가 있습니다. 약한 맵이없는 첫 번째 코드 스 니펫에서 코드 조각은 DOM 요소 사이의 모든 방식으로 참조를 저장합니다. 이렇게하면 DOM 요소가 가비지 수집되지 않습니다.(i * i) % len아무도 사용하지 않는 이상한 것처럼 보일지 모르지만 다시 생각하십시오. 많은 프로덕션 코드에는 문서 전체에 튀는 DOM 참조가 있습니다. 이제 두 번째 코드에서는 요소에 대한 모든 참조가 약하기 때문에 노드를 제거하면 브라우저에서 해당 노드가 사용되지 않는지 (코드로 도달 할 수 없음) 확인할 수 있습니다. 따라서 메모리에서 삭제하십시오. 메모리 사용과 메모리 앵커 (사용되지 않은 요소가 메모리에 유지되는 첫 번째 코드 스 니펫과 같은 것)에 대해 걱정해야하는 이유는 더 많은 메모리 사용이 더 많은 브라우저 GC 시도를 의미하기 때문에 (메모리를 확보하려고 시도하는 것) 브라우저 충돌 방지)는 브라우징 경험이 느려지고 때로는 브라우저 충돌이 발생 함을 의미합니다.

이것들에 대한 polyfill에 관해서는, 나는 내 자신의 라이브러리를 추천 할 것입니다 ( 여기에서 @ github ). 이 라이브러리는 다른 폴리 필에서 찾을 수있는 복잡한 프레임 워크없이 간단하게 폴리 필 할 수있는 매우 가벼운 라이브러리입니다.

~ 행복한 코딩!


1
명확한 설명에 감사드립니다. 예는 어떤 단어보다 가치가 있습니다.
newguy

@lolzery, Re " DOM 요소가 가비지 수집되는 것을 방지합니다. "필요한 것은 null설정 elements하기 만하면됩니다. GC 처리됩니다. & Re " 문서 전체에 튀어 나오는 DOM 참조 "는 전혀 중요하지 않습니다. 일단 메인 링크 elements가 사라지면 모든 원형 참조는 GC됩니다. 요소가 필요하지 않은 요소에 대한 참조를 보유하고 있으면 코드를 수정하고 사용을 완료하면 ref를 null로 설정하십시오 . GCed가 될 것입니다. 약점은 필요하지 않습니다 .
Pacerier

2
@Pacerier는 열정적 인 피드백에 감사하지만 elementsnull로 설정 하면 브라우저가 첫 번째 스 니펫 상황에서 요소를 GC 할 수 없습니다 . 요소에 사용자 정의 속성을 설정 한 다음 해당 요소를 계속 얻을 수 있으며 해당 사용자 정의 속성에 계속 액세스 할 수 있기 때문에 GC가 발생하지 않습니다. 그것을 금속 고리 체인처럼 생각하십시오. 체인에있는 하나 이상의 링크에 액세스 할 수있는 한 체인의 해당 링크를 잡고 전체 체인 아이템이 심연으로 떨어지는 것을 방지 할 수 있습니다.
Jack Giffin

1
vars라는 이름의 dunder를 가진 생산 코드는 구토를 만든다
Barbu Barbu

10

나는 사용한다 WeakMap 불변의 객체를 매개 변수로 취하는 함수를 걱정없이 메모하는 캐시에 합니다.

메모는 "값을 계산 한 후 캐시하여 다시 계산할 필요가 없다"고 말하는 멋진 방법입니다.

예를 들면 다음과 같습니다.

몇 가지 참고할 사항 :

  • Immutable.js 객체는 사용자가 객체를 수정할 때 새 포인터를 사용하여 새 객체를 반환하므로 WeakMap에서 키로 사용하면 동일한 계산 값이 보장됩니다.
  • WeakMap은 (키로 사용 된) 객체가 가비지 수집되면 WeakMap에서 계산 된 값도 가져 오기 때문에 메모 에 유용합니다.

1
이것은 메모리 캐시가 메모리에 민감 하고 obj / 함수 수명 동안 지속되지 않는 한 weakmap의 유효한 사용입니다 . "메모리 캐시"가 obj / 함수 수명 동안 지속되도록 의도 된 경우 weakmap은 잘못된 선택입니다. 대신 6 가지 기본 자바 스크립트 캡슐화 기술 중 하나를 사용하십시오 .
Pacerier

3

WeakMaps에 대한 간단한 기능 기반 사용 사례 / 예가 있습니다.

사용자 모음 관리

나는 진형 User그 속성 포함 개체 fullname, username, age, gender전화를하는 방법 print다른 속성의 사람이 읽을 수있는 요약을 인쇄합니다.

/**
Basic User Object with common properties.
*/
function User(username, fullname, age, gender) {
    this.username = username;
    this.fullname = fullname;
    this.age = age;
    this.gender = gender;
    this.print = () => console.log(`${this.fullname} is a ${age} year old ${gender}`);
}

그런 다음에 users의해 키가 지정된 여러 사용자의 모음을 유지하기 위해 호출 된 맵을 추가 했습니다 username.

/**
Collection of Users, keyed by username.
*/
var users = new Map();

또한 Collection을 추가하려면 사용자를 추가, 가져 오기, 삭제하기위한 도우미 기능과 완전성을 위해 모든 사용자를 인쇄하는 기능도 필요했습니다.

/**
Creates an User Object and adds it to the users Collection.
*/
var addUser = (username, fullname, age, gender) => {
    let an_user = new User(username, fullname, age, gender);
    users.set(username, an_user);
}

/**
Returns an User Object associated with the given username in the Collection.
*/
var getUser = (username) => {
    return users.get(username);
}

/**
Deletes an User Object associated with the given username in the Collection.
*/
var deleteUser = (username) => {
    users.delete(username);
}

/**
Prints summary of all the User Objects in the Collection.
*/
var printUsers = () => {
    users.forEach((user) => {
        user.print();
    });
}

NodeJS 와 같은 위의 모든 코드를 실행 하면 users맵 만 전체 프로세스 내에서 사용자 객체에 대한 참조를 갖습니다. 개별 사용자 개체에 대한 다른 참조는 없습니다.

이 코드를 대화식 NodeJS 쉘로 실행하는 예를 들어 네 명의 사용자를 추가하고 인쇄합니다. 사용자 추가 및 인쇄

기존 코드를 수정하지 않고 사용자에게 더 많은 정보 추가

이제 각 사용자 SMP (소셜 미디어 플랫폼) 링크를 사용자 개체와 함께 추적해야하는 새로운 기능이 필요하다고 가정합니다.

여기서 핵심은이 기능이 기존 코드에 대한 최소한의 개입으로 구현되어야한다는 것입니다.

이는 다음과 같은 방식으로 WeakMaps에서 가능합니다.

Twitter, Facebook, LinkedIn에 대해 별도의 WeakMaps 3 개를 추가합니다.

/*
WeakMaps for Social Media Platforms (SMPs).
Could be replaced by a single Map which can grow
dynamically based on different SMP names . . . anyway...
*/
var sm_platform_twitter = new WeakMap();
var sm_platform_facebook = new WeakMap();
var sm_platform_linkedin = new WeakMap();

getSMPWeakMap주어진 SMP 이름과 관련된 WeakMap을 반환하기 위해 도우미 함수 가 추가되었습니다.

/**
Returns the WeakMap for the given SMP.
*/
var getSMPWeakMap = (sm_platform) => {
    if(sm_platform == "Twitter") {
        return sm_platform_twitter;
    }
    else if(sm_platform == "Facebook") {
        return sm_platform_facebook;
    }
    else if(sm_platform == "LinkedIn") {
        return sm_platform_linkedin;
    }
    return undefined;
}

지정된 SMP WeakMap에 사용자 SMP 링크를 추가하는 기능입니다.

/**
Adds a SMP link associated with a given User. The User must be already added to the Collection.
*/
var addUserSocialMediaLink = (username, sm_platform, sm_link) => {
    let user = getUser(username);
    let sm_platform_weakmap = getSMPWeakMap(sm_platform);
    if(user && sm_platform_weakmap) {
        sm_platform_weakmap.set(user, sm_link);
    }
}

지정된 SMP에있는 사용자 만 인쇄하는 기능입니다.

/**
Prints the User's fullname and corresponding SMP link of only those Users which are on the given SMP.
*/
var printSMPUsers = (sm_platform) => {
    let sm_platform_weakmap = getSMPWeakMap(sm_platform);
    console.log(`Users of ${sm_platform}:`)
    users.forEach((user)=>{
        if(sm_platform_weakmap.has(user)) {
            console.log(`\t${user.fullname} : ${sm_platform_weakmap.get(user)}`)
        }
    });
}

이제 각 사용자가 여러 SMP에 대한 링크를 가질 수 있도록 사용자에 대한 SMP 링크를 추가 할 수 있습니다.

... 이전 예제에서 계속해서 사용자에게 SMP 링크, 사용자 Bill 및 Sarah에 대한 여러 링크를 추가 한 다음 각 SMP에 대한 링크를 별도로 인쇄합니다. 사용자에게 SMP 링크 추가 및 표시

이제 users를 호출 하여 지도 에서 사용자가 삭제되었다고 가정합니다 deleteUser. 사용자 개체에 대한 유일한 참조가 제거됩니다. 또한 사용자 오브젝트가 없으면 SMP 링크에 액세스 할 수있는 방법이 없기 때문에 가비지 콜렉션에 의한 모든 SMP WeakMaps에서 SMP 링크를 지 웁니다.

... 예제를 계속 진행하면서 사용자 Bill을 삭제 하고 연관된 SMP 링크를 인쇄합니다.

맵에서 사용자 Bill을 삭제하면 SMP 링크도 제거됩니다.

SMP 링크를 개별적으로 삭제하기위한 추가 코드와이 기능이 수정되지 않은 기존 코드는 별도로 필요하지 않습니다.

WeakMaps를 사용하거나 사용하지 않고이 기능을 추가하는 다른 방법이 있으면 언제든지 의견을 말하십시오.


_____nice______
Aleks
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.