kzen.dev
  • Întrebări
  • Tag-uri
  • Utilizatori
Notificări
Recompense
Înregistrare
După înregistrare, veți primi notificări despre răspunsurile și comentariile la întrebările DVS.
Logare
Dacă aveţi deja un cont, autentificaţi-vă pentru a verifica notificările noi.
Aici vor fi recompensele pentru întrebările, răspunsurile și comentariile adăugate sau modificate.
Mai mult
Sursă
Editează
 valderman
valderman
Question

Care sunt utilizările actuale de ES6 WeakMap?

Care sunt utilizările actuale ale WeakMap structura de date introduse în ECMAScript 6?

Când o cheie de o harta slab creează o puternică referire la valoarea corespunzătoare, asigurându-se că o valoare care a fost introdus într-o harta slab va nu dispară atâta timp cât cheia este încă în viață, se poate't fi folosit pentru memo tabele, cache-uri sau orice altceva care le-ar folosi în mod normal referințe slabe, hărți cu slabe valori, etc. pentru.

Mi se pare ca acest lucru:

weakmap.set(key, value);

...este doar un mod de a spune acest lucru:

key.value = value;

Ce beton cazuri de utilizare sunt eu lipsesc?

373 2015-04-02T12:39:05+00:00 5
 valderman
valderman
Întrebarea editată 2 aprilie 2015 в 9:44
Programare
javascript
ecmascript-6
weakmap
Solution / Answer
Benjamin Gruenbaum
Benjamin Gruenbaum
2 aprilie 2015 в 3:09
2015-04-02T15:09:00+00:00
Mai mult
Sursă
Editează
#27189681

Fundamental

WeakMaps oferi o modalitate de a extinde obiecte din exterior, fără a interfera cu colectarea gunoiului. Ori de câte ori doriți să se extindă un obiect, dar poate't pentru că acesta este sigilat - sau de la o sursă externă - o WeakMap pot fi aplicate.

Un WeakMap este o hartă (dicționar) unde tastele sunt slabe - care este, dacă toate trimiterile la key sunt pierdut și nu există mai multe referiri la valoare - value poate fi de gunoi colectate. Las's show această primă prin exemple, atunci explic un pic si termina în cele din urmă cu utilizarea reală.

Las's spun I'm, folosind un API care dă un anumit obiect:

var obj = getObjectFromLibrary();

Acum, eu am o metodă care folosește la obiect:

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

Vreau să țineți evidența cât de multe ori metoda a fost numit cu un anumit obiect și să raporteze dacă se întâmplă mai mult de N ori. Cu naivitate unul ar fi că pentru a utiliza o Hartă:

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

Aceasta funcționează, dar are o scurgere de memorie - ne acum ține evidența fiecare bibliotecă obiectul a trecut de la funcția pe care o păstrează la biblioteca de obiecte de la a fi gunoi colectate. În loc să - putem folosi o 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);
}

Și scurgeri de memorie este plecat.

Cazuri de utilizare

Unele cazuri de utilizare, care altfel ar provoca o scurgere de memorie și sunt activate prin `WeakMap se includ:

  • Păstrarea datelor private despre un anumit obiect și numai oferindu-acces pentru persoanele cu o trimitere la Hartă. O mai ad-hoc abordare este de a veni cu privat-simboluri propunere, dar care's o lungă perioadă de timp de acum.
  • Păstrarea datelor despre bibliotecă de obiecte, fără a le modifica sau de a suporta cheltuielile.
  • Păstrarea datelor despre un mic set de obiecte în cazul în care mai multe obiecte de tip exista pentru a nu atrage probleme ascunse cu clasele JS motoare utilizează pentru obiecte de același tip.
  • Păstrarea datelor despre găzdui obiecte, cum ar fi noduri DOM în browser-ul.
  • Adăugarea de capacitatea de a un obiect din exterior (cum ar fi cazul emițător de exemplu în alt raspuns).

Să's se uite la un real folos

Acesta poate fi folosit pentru a extinde un obiect din exterior. Las's dea o practice (adaptat, un fel de real - pentru a face un punct) exemplu din lumea reală a Node.js.

Las's spun te're Node.js și ai Promit obiecte - acum doriți să urmăriți de toate, în prezent, respinse promisiuni - cu toate acestea, aveți nu doriți să păstrați-le de gunoi colectate în cazul în care nu există referințe la ele.

Acum, nu't_ doriți să adăugați proprietăți la obiectele native din motive evidente - deci're blocat. Dacă vă păstrați trimiteri la promisiunile pe care le're provocând o scurgere de memorie deoarece nu de colectare a gunoiului se poate întâmpla. Dacă tu nu't ține referințe apoi, puteți't de a salva informații suplimentare despre anumite promisiuni. Orice sistem care implică salvarea ID-ul de o promisiune, în mod inerent, înseamnă că ai nevoie de o trimitere la acesta.

Intra WeakMaps

WeakMaps înseamnă că tastele sunt slabe. Nu există modalități de a enumera o harta slab sau pentru a obține toate valorile sale. Într-un slab hartă, puteți stoca datele bazate pe o cheie și atunci când cheia se devine gunoi colectate deci, nu valorile.

Acest lucru înseamnă că, având o promisiune puteți stoca stat despre asta - și de acel obiect poate fi încă de gunoi colectate. Mai târziu, dacă veți obține o referință la un obiect, puteți verifica dacă aveți orice stat cu privire la acesta și să-l raporteze.

Acest lucru a fost folosit pentru a pune în aplicare netratată respingere cârlige de Petka Antonov ca aceasta:

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

Vom păstra informații despre promisiuni într-o hartă și poate ști când a fost respinsă o promisiune a fost manipulat.

 nakhodkiin
nakhodkiin
Răspuns editat 9 februarie 2019 в 2:51
474
0
 axelduch
axelduch
2 aprilie 2015 в 12:48
2015-04-02T12:48:53+00:00
Mai mult
Sursă
Editează
#27189680

Acest răspuns pare să fie părtinitoare și inutilizabile într-un scenariu de lumea reală. Vă rugăm să citiți-l așa cum este, și don't ia în considerare ca o optiune pentru nimic altceva decât experimentare

Un caz de utilizare ar putea fi să-l folosească ca un dicționar pentru ascultători, am un coleg care a facut asta. Este foarte util pentru orice ascultător este direct indreptat cu acest mod de a face lucrurile. La revedere ascultător.pe.

Dar de o mai abstract punct de vedere, WeakMap este deosebit de puternic pentru a dematerializa acces la practic nimic, nu't nevoie de un spațiu de nume pentru a izola membrii săi, deoarece este deja implicat de natura acestei structuri. Am'm destul de sigur că ai putea face unele majore îmbunătățiri de memorie prin înlocuirea awkwards redundante obiect chei (chiar dacă deconstruirea functioneaza pentru tine).


Înainte de a citi ceea ce este următoarea

Eu acum seama mea sublinia nu este exact cel mai bun mod de a aborda problema și cum Benjamin Gruenbaum a subliniat (a verifica afară de răspunsul lui, dacă-l's nu este deja mai presus de a mea :p), această problemă nu ar fi putut fi rezolvate cu un regular "Harta", deoarece s-ar fi scurs, astfel, principala forță de WeakMap` este că nu interferează cu colectarea gunoiului având în vedere că ele nu păstrează o referință.


Aici este codul actual de colegul meu (datorită l pentru sharing)

Sursa completa aici, l's despre ascultatorii de management despre care am vorbit mai sus (puteți, de asemenea, să ia o privire la specificatii)

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);
    }
}
 axelduch
axelduch
Răspuns editat 18 septembrie 2017 в 6:50
47
0
Michael Horojanski
Michael Horojanski
25 octombrie 2016 в 1:45
2016-10-25T13:45:55+00:00
Mai mult
Sursă
Editează
#27189682

WeakMap funcționează bine pentru încapsularea și ascunderea de informații

WeakMap este disponibil numai pentru ES6 și mai sus. O WeakMap este o colecție de perechi de valori-cheie și în cazul în care cheia trebuie să fie un obiect. În următorul exemplu, vom construi o WeakMap cu două elemente:

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

Am folosit set () metoda pentru a defini o asociere între un obiect și un alt element (un șir de caractere în cazul nostru). Am folositget () metoda pentru a prelua elementul asociate cu un obiect. Cel mai interesant aspect al WeakMap este faptul ca are o slabă referință la cheia în interiorul hărții. O slabă referință înseamnă că, dacă obiectul este distrus, colectorul de gunoi va elimina întreaga intrare dinWeakMap`, prin urmare, eliberarea de memorie.

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;
    }());
})()
Yangshun Tay
Yangshun Tay
Răspuns editat 27 decembrie 2017 в 8:12
16
0
Rico Kahler
Rico Kahler
17 septembrie 2017 в 11:25
2017-09-17T11:25:08+00:00
Mai mult
Sursă
Editează
#27189684

Eu folosesc WeakMap pentru cache-ul de griji-free memoization de funcții care ia în imuabile obiecte ca parametru.

Memoization este în mod fantezist de a spune "după ce a calcula valoarea, cache, astfel încât să don't au pentru a calcula din nou".

Aici's un exemplu:

// using immutable.js from here https://facebook.github.io/immutable-js/

const memo = new WeakMap();

let myObj = Immutable.Map({a: 5, b: 6});

function someLongComputeFunction (someImmutableObj) {
  // if we saved the value, then return it
  if (memo.has(someImmutableObj)) {
    console.log('used memo!');
    return memo.get(someImmutableObj);
  }

  // else compute, set, and return
  const computedValue = someImmutableObj.get('a') + someImmutableObj.get('b');
  memo.set(someImmutableObj, computedValue);
  console.log('computed value');
  return computedValue;
}

someLongComputeFunction(myObj);
someLongComputeFunction(myObj);
someLongComputeFunction(myObj);

// reassign
myObj = Immutable.Map({a: 7, b: 8});

someLongComputeFunction(myObj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.1/immutable.min.js"></script>

Câteva lucruri de reținut:

  • Immutable.js obiecte reveni obiecte noi (cu un nou pointer) când modificați-le astfel încât utilizarea lor în calitate de chei într-un WeakMap se garantează aceeași valoare calculată.
  • La WeakMap este mare pentru note, pentru că odată ce obiectul (folosit ca o cheie) devine gunoi colectate, nu atât de valoarea calculată pe WeakMap.
 Pacerier
Pacerier
Răspuns editat 18 septembrie 2017 в 8:56
10
0
Jack Giffin
Jack Giffin
6 august 2017 в 10:54
2017-08-06T22:54:50+00:00
Mai mult
Sursă
Editează
#27189683

𝗠𝗲𝘁𝗮𝗱𝗮𝘁𝗮

Slab Hărți pot fi utilizate pentru a stoca metadate despre DOM elemente, fără a interfera cu colectarea gunoiului sau de a face colegii nebun la cod. De exemplu, ai putea să le utilizeze pentru a indice numeric tuturor elementelor într-o pagină web.

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

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[Math.pow(i, 2) % 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[Math.pow(i, 2) % 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"
  )   // }
);

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

Diferența poate arata neglijabil, în afară de faptul că weakmap versiune este mai lung, cu toate acestea, există o diferență majoră între cele două bucăți de cod prezentate mai sus. În primul fragment de cod, fără a slabi hărți, bucata de cod magazine trimiterile de orice fel care între elementele DOM. Acest lucru previne DOM elemente de gunoi colectate. Matematica.pow(i, 2) % len] poate părea ciudat că nimeni nu s-ar folosi, dar cred că din nou: o mulțime de codul de producție a DOM referințe care topaie peste tot în document. Acum, pentru cea de-a doua bucată de cod, pentru că toate referirile la elemente sunt slab, atunci când o elimina un nod, browser-ul este capabil de a determina care nodul nu este folosit (nu putea fi atins de cod), și, astfel, a șterge din memorie. Motivul pentru care ar trebui să fie preocupat de utilizarea memoriei, și ancore de memorie (cum ar fi primul fragment de cod în cazul în care elemente neutilizate sunt păstrate în memorie) pentru că este mai multă memorie de utilizare înseamnă mai mult de browser-ul GC-încearcă (să încercați pentru a elibera memorie pentru a evita un accident de browser-ul) înseamnă mai lent experiență de navigare și, uneori, un accident de browser-ul.

Ca pentru un polyfill pentru acestea, aș recomanda biblioteca mea (găsite aici @ github). Este un foarte ușor de bibliotecă, care vor pur și simplu polyfill fără nici din cale-prea-complex de cadre s-ar putea găsi în alte polyfills.

~ Codificare fericit!

Jack Giffin
Jack Giffin
Răspuns editat 6 iulie 2019 в 11:22
9
0
Comunități asemănătoare 1
JavaScript, România - Moldova
JavaScript, România - Moldova
285 utilizatori
Comunitatea Română JavaScript: github.com/js-ro Pentru confort, opriți notificările. Parteneri: @php_ro, @python_ro, @devops_ro, @seo_ro Offtop: @holywars_ro
Deschide telegram
Adăugati o întrebare
Categorii
Toate
Tehnologii
Cultură
Viață / Artă
Stiință
Profesii
Afaceri
Utilizatori
Toate
Nou
Populare
1
工藤 芳則
Înregistrat 6 zile în urmă
2
Ирина Беляева
Înregistrat 1 săptămână în urmă
3
Darya Arsenyeva
Înregistrat 1 săptămână în urmă
4
anyta nuam-nuam (LapuSiK)
Înregistrat 1 săptămână în urmă
5
Shuhratjon Imomkulov
Înregistrat 1 săptămână în urmă
ID
JA
KO
RO
RU
© kzen.dev 2023
Sursă
stackoverflow.com
în cadrul licenței cc by-sa 3.0 cu atribuire