ES6 WeakMap'in gerçek kullanım alanları nelerdir?


397

WeakMapECMAScript 6'da sunulan veri yapısının gerçek kullanım alanları nelerdir ?

Zayıf bir haritanın anahtarı, karşılık gelen değerine güçlü bir referans oluşturduğundan, zayıf bir haritaya eklenen bir değerin , anahtarı hala canlı olduğu sürece hiçbir zaman kaybolmamasını sağladığından, not tabloları için kullanılamaz, önbellekleri veya normalde zayıf referansları, zayıf değerlere sahip haritaları vb.

Bana öyle geliyor ki:

weakmap.set(key, value);

... bunu söylemenin basit bir yolu:

key.value = value;

Hangi somut kullanım örneklerini kaçırıyorum?




35
Gerçek dünya kullanım durumu: DOM düğümleri için özel verileri saklayın.
Felix Kling

Zayıf referanslar için bahsettiğiniz tüm kullanım durumları da çok önemlidir. Belirsizliği tanıttıkları için dile eklemek çok daha zordur. Mark Miller ve diğerleri zayıf referanslar üzerinde çok çalıştılar ve sanırım sonunda geliyorlar. Sonunda
Benjamin Gruenbaum

2
WeakMaps bellek sızıntılarını tespit etmek için kullanılabilir: stevehanov.ca/blog/?id=148
theWebalyst

Yanıtlar:


513

esasen

WeakMaps, çöp toplama işlemine müdahale etmeden nesneleri dışarıdan genişletmenin bir yolunu sunar. Bir nesneyi genişletmek istediğinizde, ancak mühürlendiğinden (veya harici bir kaynaktan) yapılamadığında, bir WeakMap uygulanabilir.

WeakMap, anahtarların zayıf olduğu bir haritadır (sözlük) - yani, anahtarın tüm referansları kaybolursa ve değere daha fazla referans yoksa - değer çöp toplanabilir. Bunu önce örneklerle gösterelim, sonra biraz açıklayalım ve son olarak gerçek kullanımla bitirelim.

Diyelim ki bana belirli bir nesneyi veren bir API kullanıyorum:

var obj = getObjectFromLibrary();

Şimdi, nesneyi kullanan bir yöntem var:

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

Yöntemin belirli bir nesneyle kaç kez çağrıldığını takip etmek ve N kereden fazla olup olmadığını rapor etmek istiyorum. Safça bir Harita kullanmayı düşünebilirsiniz:

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);
}

Bu çalışıyor, ancak bir bellek sızıntısı var - artık işleve iletilen her bir kütüphane nesnesini izleyerek kütüphane nesnelerinin çöp toplanmasını önler. Bunun yerine - şunu kullanabiliriz 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);
}

Ve bellek sızıntısı gitti.

Kullanım örnekleri

Aksi takdirde bellek sızıntısına neden olabilecek ve WeakMaps tarafından etkinleştirilen bazı kullanım durumları şunlardır:

  • Belirli bir nesne hakkında özel verileri tutmak ve yalnızca Haritaya referans veren kişilere erişmesine izin vermek. Özel semboller önerisi ile daha geçici bir yaklaşım geliyor ama bu uzun zaman alıyor.
  • Kütüphane nesneleri hakkındaki verileri değiştirmeden veya ek yüke maruz bırakmadan tutma.
  • JS motorlarının aynı türdeki nesneler için kullandığı gizli sınıflarla ilgili sorunlara yol açmamak için birçok nesnenin bulunduğu küçük bir nesne kümesi hakkında veri tutma.
  • Tarayıcıda DOM düğümleri gibi ana bilgisayar nesneleri hakkındaki verileri tutma.
  • Bir nesneye dışarıdan bir yetenek ekleme (diğer yanıttaki olay yayıcı örneği gibi).

Gerçek bir kullanıma bakalım

Bir nesneyi dışarıdan uzatmak için kullanılabilir. Düğümün gerçek dünyasından pratik (uyarlanmış, bir çeşit gerçek - bir noktaya değinmek) örneği verelim. Js.

Diyelim sen node.js söylemek ve sahip Promisenesneleri - şimdi tüm halen reddedilen sözlere takip etmek istiyoruz - ancak, do not hiçbir referanslar kendilerine mevcut durumda toplanan çöp olmaktan onları tutmak istiyorum.

Şimdi, yok bariz nedenlerden yerli nesnelere özellikler eklemek istiyorum - takılıp konum. Çöp toplama işlemi yapılamayacağı için bellek sızıntısına neden olduğunuz sözleri referans alırsanız. Referansları tutmazsanız, bireysel vaatler hakkında ek bilgi kaydedemezsiniz. Bir sözün kimliğini doğal olarak kaydetmeyi içeren herhangi bir şema, ona bir referansa ihtiyacınız olduğu anlamına gelir.

WeakMaps girin

WeakMaps anahtarların zayıf olduğu anlamına gelir . Zayıf bir haritayı numaralandırmanın veya tüm değerlerini elde etmenin bir yolu yoktur. Zayıf bir haritada, verileri bir anahtara göre ve anahtar ne zaman toplanırsa değerleri de saklayabilirsiniz.

Bu, bir söz verdiğinizde bu konuda durumu depolayabileceğiniz anlamına gelir - ve bu nesne yine de çöp toplanabilir. Daha sonra, bir nesneye referans alırsanız, onunla ilgili herhangi bir durumunuz olup olmadığını kontrol edebilir ve raporlayabilirsiniz.

Bu uygulamaya kullanıldı işlenmeyen ret kancaları olarak Petka Antonov tarafından bu :

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
});

Bir haritadaki vaatlerle ilgili bilgileri tutarız ve reddedilen bir vaatin ne zaman ele alındığını bilebiliriz.


8
Merhaba! Örnek kodun hangi kısmının bellek sızıntısına neden olduğunu söyler misiniz?
ltamajs

15
@ ltamajs4 emin, bir useObjörnek Mapdeğil, a kullanarak örnekte WeakMapaktarılan nesneyi bir harita anahtarı olarak kullanıyoruz. Nesne asla haritadan kaldırılmaz (ne zaman yapacağımızı bilemeyeceğimiz için), bu nedenle her zaman bir referans vardır ve asla çöp toplanamaz. WeakMap örneğinde, nesneye yapılan tüm diğer başvurular kaybolur giderilmez, nesne 'den temizlenebilir WeakMap. Ne demek istediğimden hala emin değilseniz lütfen bana bildirin
Benjamin Gruenbaum

@Benjamin, Belleğe duyarlı bir önbellek gereksinimi ile data_object tuple gereksinimi arasında ayrım yapmamız gerekiyor. Bu iki ayrı gereksinimi birbirine karıştırmayın. Sizin calledörnek daha iyi kullanılarak yazılır jsfiddle.net/f2efbm7z ve zayıf bir harita kullanımını göstermek etmez. Aslında, aşağıda listeleyeceğim toplam 6 şekilde daha iyi yazılabilir .
Pacerier

Temel olarak, zayıf haritanın amacı belleğe duyarlı bir önbellektir. Nesneleri dışarıdan genişletmek için kullanılabilirken, bu tanımsız bir berbat hack'tir ve kesinlikle uygun amacı değildir .
Pacerier

1
Bir vaat ile onun kaç kez ele alındığı / reddedildiği arasındaki bağlantıyı korumak istiyorsanız, 1) sembolünü kullanın ; p[key_symbol] = data. veya 2) benzersiz adlandırma; p.__key = data. veya 3) özel kapsam; (()=>{let data; p.Key = _=>data=_;})(). veya 4) 1 veya 2 veya 3 ile vekil. veya 5) Promise sınıfını 1 veya 2 veya 3 ile değiştirin / uzatın . veya 6) Promise sınıfını bir grup gerekli üyeyle değiştirin / uzatın. - Her durumda, belleğe duyarlı bir önbelleğe ihtiyacınız olmadığı sürece zayıf haritaya gerek yoktur.
Pacerier

48

Bu cevap, gerçek dünya senaryosunda önyargılı ve kullanılamaz görünüyor. Lütfen olduğu gibi okuyun ve denemekten başka bir şey için gerçek bir seçenek olarak düşünmeyin.

Bir kullanım örneği dinleyiciler için sözlük olarak kullanmak olabilir, bunu yapan bir iş arkadaşım var. Çok yararlıdır, çünkü herhangi bir dinleyici doğrudan bu şekilde bir şeyler yapmayı hedefler. Hoşçakalın listener.on.

Ancak daha soyut bir bakış açısından, WeakMaptemelde herhangi bir şeye erişimi kaydileştirmek için özellikle güçlüdür, üyelerini izole etmek için bir ad alanına ihtiyacınız yoktur, çünkü bu yapının doğası tarafından zaten ima edilmiştir. Garip gereksiz yedek anahtarları değiştirerek bazı önemli bellek iyileştirmeleri yapabileceğinizden eminim (yapısökme sizin için işe yarıyor olsa bile).


Okumadan önce sırada ne var

Şimdi vurgulamamın problemle başa çıkmanın en iyi yolu olmadığını ve Benjamin Gruenbaum'un işaret ettiği gibi (cevabını kontrol et, eğer benimkinin üstünde değilse: p), bu sorun düzenli olarak çözülemezdi Map, çünkü sızdıracaktı, bu yüzden ana gücü, WeakMapbir referans tutmadıkları sürece çöp toplamaya müdahale etmemesidir.


İşte iş arkadaşımın gerçek kodu ( paylaşım için ona teşekkürler )

Tam kaynak burada , yukarıda bahsettiğim dinleyici yönetimi ile ilgili (ayrıca özelliklere de bakabilirsiniz )

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
Bunu nasıl kullanacağını pek anlamıyorum. Gözlemlenebilir olanın, artık başvurulmadığında kendisine bağlı olaylar ile birlikte çökmesine neden olur. Sahip olduğum sorun, Observer artık başvurulmadığı zaman. Bence buradaki çözüm sorunun yarısını çözdü. WeakMap ile gözlemci problemini çözülemez diye çözemeyeceğini sanmıyorum.
jgmjgm

1
Çift tamponlu olay dinleyicileri diğer dillerde hızlı olabilir, ancak bu durumda sadece düz ezoterik ve yavaştır. Bu benim üç sentim.
Jack Giffin

@axelduch, Vay canına bu dinleyici-kolu efsanesi Javascript topluluğuna kadar seyredildi ve 40 oy aldı! Bu cevabın neden tamamen yanlış olduğunu anlamak için stackoverflow.com/a/156618/632951
Pacerier

1
@Pacerier cevabı güncelledi, geri bildiriminiz için teşekkürler
axelduch

1
@axelduch, Evet, oradan da bir ref var.
Pacerier

18

WeakMap kapsülleme ve bilgi gizleme için iyi çalışır

WeakMapyalnızca ES6 ve üstü için kullanılabilir. A WeakMap, anahtarın bir nesne olması gereken anahtar ve değer çiftlerinden oluşan bir koleksiyondur. Aşağıdaki örnekte, WeakMapiki öğeli bir a oluşturuyoruz:

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()Yöntemi, bir nesne ve başka bir öğe (bizim durumumuzda bir dize) arasında bir ilişki tanımlamak için kullandık . get()Bir nesneyle ilişkili öğeyi almak için yöntemi kullandık . S'nin ilginç yönü WeakMap, haritanın içindeki tuşa zayıf bir referans göstermesidir. Zayıf bir başvuru, nesne yok edilirse, çöp toplayıcının tüm girdiyi oradan kaldıracağı ve WeakMapböylece belleği boşaltacağı anlamına gelir.

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
Re "zayıf harita kapsülleme ve bilgi gizleme için iyi çalışır". Sadece yapabileceğiniz için yapmanız gerektiği anlamına gelmez. Javascript, zayıf harita icat edilmeden önce bile kapsülleme ve bilgi gizleme için varsayılan yöntemlere sahiptir. Şu anda olduğu gibi, bunu yapmanın 6 yolu var . Kapsülleme yapmak için zayıf harita kullanmak çirkin bir facepalmdır.
Pacerier

12

𝗠𝗲𝘁𝗮𝗱𝗮𝘁𝗮

Zayıf Haritalar, çöp toplama işlemine müdahale etmeden veya iş arkadaşlarınızı kodunuza deli etmeden DOM öğeleri hakkındaki meta verileri depolamak için kullanılabilir. Örneğin, bunları bir web sayfasındaki tüm öğeleri sayısal olarak dizine eklemek için kullanabilirsiniz.

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

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"
  )   // }
);

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

Zayıf harita versiyonunun daha uzun olması dışında, fark göz ardı edilebilir görünebilir, ancak yukarıda gösterilen iki kod parçası arasında büyük bir fark vardır. Kodun ilk snippet'inde, zayıf haritalar olmadan, kod parçası referansları DOM öğeleri arasında her şekilde saklar. Bu, DOM öğelerinin çöp toplanmasını önler.(i * i) % lenkimsenin kullanamayacağı bir tuhaflık gibi görünebilir, ancak tekrar düşünün: bol miktarda üretim kodu belgenin her yerinde zıplayan DOM referanslarına sahiptir. Şimdi, ikinci kod parçası için, öğelere yapılan tüm referanslar zayıf olduğundan, bir düğümü kaldırdığınızda, tarayıcı düğümün kullanılmadığını (kodunuz tarafından erişilemediğini) belirleyebilir ve böylece bellekten silin. Bellek kullanımı ve bellek çapaları (kullanılmayan öğelerin bellekte tutulduğu ilk kod snippet'i gibi) hakkında endişelenmeniz gerekmesinin nedeni, daha fazla bellek kullanımı daha fazla tarayıcı GC denemesi anlamına gelir (belleği boşaltmaya çalışmak için) tarayıcı çökmesini önleme) daha yavaş tarama deneyimi ve bazen de tarayıcı çökmesi anlamına gelir.

Bunlar için bir çoklu dolgu gelince, kendi kütüphanemi tavsiye ederim ( burada @ github bulundu ). Diğer çok amaçlı dolgularda bulabileceğiniz aşırı karmaşık çerçevelerden herhangi biri olmadan onu kolayca dolduracak çok hafif bir kütüphanedir.

~ Mutlu kodlama!


1
Açık açıklama için teşekkürler. Bir örnek her kelimeden daha değerli.
newguy

@lolzery, Re " Bu, DOM öğelerinin çöp toplanmasını önler ", tek ihtiyacınız olan null olarak ayarlamakelements ve işiniz bitti: GCed olacak. & Re " Belgenin her yerindeelements seken DOM başvuruları " hiç önemli değil: Ana bağlantı kaybolduğunda, tüm dairesel ref GCed olur. Öğeniz, ihtiyaç duymadığı öğeye referanslar tutuyorsa, kodu düzeltin ve kullanmayı bitirdiğinizde ref değerini null değerine ayarlayın . GCed edilecek. Zayıf haritalara gerek yoktur .
Pacerier

2
@Pacerier Ancak ayarlayarak, senin hevesli geri bildirimler için teşekkür elementsedecektir null değil ilk pasajı durumda elemanlar GC tarayıcıyı tanır. Bunun nedeni, öğeler üzerinde özel özellikler ayarlamanız ve daha sonra bu öğelerin yine de elde edilebilmesi ve özel özelliklerine hala erişilebilmesidir, böylece bunların GC'lenmesini engeller. Bir metal halka zinciri gibi düşünün. Zincirdeki en az bir bağlantıya erişiminiz olduğu sürece, zincirdeki o bağlantıya tutunabilir ve böylece tüm öğe zincirinin uçuruma düşmesini önleyebilirsiniz.
Jack Giffin

1
vars adlı dunder ile üretim kodu kusmama neden oluyor
Barbu Barbu

10

Kullandığım WeakMapkendi parametre olarak sabit nesneler almak işlevlerin sorunsuz memoization önbelleğine için.

Memoization, "değeri hesapladıktan sonra önbelleğe alın, böylece tekrar hesaplamanıza gerek yok" demenin süslü bir yoludur.

İşte bir örnek:

Unutulmaması gereken birkaç nokta:

  • Immutable.js nesneleri, onları değiştirdiğinizde yeni nesneleri döndürür (yeni bir işaretçi ile), böylece WeakMap'te anahtar olarak kullanmak aynı hesaplanmış değeri garanti eder.
  • WeakMap notlar için mükemmeldir çünkü nesne (anahtar olarak kullanılır) çöp toplandığında, WeakMap üzerinde hesaplanan değer de olur.

1
Notlama önbelleğinin obj / işlev ömrü boyunca kalıcı değil, belleğe duyarlı olması gerektiği sürece, bu zayıf haritanın geçerli bir kullanımıdır . "Not önbelleği" obj / fonksiyon ömrü boyunca kalıcı olacaksa, zayıf harita yanlış seçimdir: Bunun yerine 6 varsayılan javascript kapsülleme tekniğinden herhangi birini kullanın.
Pacerier

3

Bu basit özellik tabanlı kullanım durumu / WeakMaps için örnek var.

KULLANICI KOLEKSİYONUNU YÖNETİN

Ben çıkıyor User, özellikleri bir içermektedir Nesne fullname, username, age, genderdenilen ve bir yöntem printdiğer özelliklerinin bir insan okunabilir bir özetini yazdırır.

/**
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}`);
}

Daha sonra users, anahtarlanan birden fazla kullanıcının bir koleksiyonunu tutmak için çağrılan bir Harita ekledim username.

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

Koleksiyonun eklenmesi, bir Kullanıcı eklemek, almak, silmek için yardımcı işlevler ve hatta bütün kullanıcıların tamlık uğruna yazdırmak için bir işlev gerektiriyordu.

/**
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();
    });
}

Yukarıdaki kodun tamamı, örneğin NodeJS çalıştığında , yalnızca usersHarita tüm işlem içinde Kullanıcı Nesneleri referansına sahiptir. Tek tek Kullanıcı Nesneleri için başka bir referans yoktur.

Bu kodu interaktif bir NodeJS kabuğu olarak çalıştırarak, Örnek olarak dört kullanıcı ekleyip yazdırıyorum: Kullanıcı ekleme ve yazdırma

MEVCUT KODU DEĞİŞTİRMEYEN KULLANICILARA DAHA FAZLA BİLGİ EKLE

Şimdi her kullanıcının Sosyal Medya Platformu (SMP) bağlantılarının Kullanıcı Nesneleri ile birlikte izlenmesi gereken yeni bir özellik gerektiğini söyleyin.

Buradaki anahtar, bu özelliğin mevcut koda minimum müdahale ile uygulanması gerektiğidir.

Bu WeakMaps ile aşağıdaki şekilde mümkündür.

Twitter, Facebook, LinkedIn için üç ayrı WeakMaps ekliyorum.

/*
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();

getSMPWeakMapBelirli bir SMP adıyla ilişkili WeakMap'i döndürmek için bir yardımcı işlev eklenir.

/**
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;
}

Verilen SMP WeakMap'e kullanıcı SMP bağlantısı ekleme işlevi.

/**
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);
    }
}

Yalnızca belirtilen SMP'de bulunan kullanıcıları yazdırma işlevi.

/**
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)}`)
        }
    });
}

Artık kullanıcılar için SMP bağlantıları da ekleyebilirsiniz, ayrıca her kullanıcının birden fazla SMP'de bir bağlantıya sahip olma olasılığı da vardır.

... önceki Örnekle devam ederek, kullanıcılara SMP bağlantıları, Bill ve Sarah kullanıcıları için birden çok bağlantı ekledim ve her SMP için bağlantıları ayrı ayrı yazdırıyorum: Kullanıcılara SMP bağlantıları ekleme ve görüntüleme

Şimdi bir Kullanıcının usersarayarak Haritadan silindiğini varsayalım deleteUser. Bu, Kullanıcı Nesnesi için tek başvuruyu kaldırır. Bu da Kullanıcı Nesnesi olmadan SMP bağlantısına erişmenin bir yolu olmadığından SMP bağlantısını SMP WeakMaps'in (Çöp Toplama yoluyla) herhangi birinden / tümünden temizleyecektir.

... Örnek ile devam ederek, kullanıcı Bill'i silip ilişkilendirilmiş SMP'lerin bağlantılarını yazdırıyorum:

Kullanıcı Faturasını Haritadan silmek SMP bağlantılarını da kaldırır

SMP bağlantısını ayrı ayrı silmek için herhangi bir ek kod gerekmez ve bu özellik hiçbir şekilde değiştirilmeden önce mevcut kod.

Bu özelliği WeakMaps ile / WeakMaps olmadan eklemenin başka bir yolu varsa lütfen yorum yapmaktan çekinmeyin.


_____nice______
Aleks
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.