zpět k lekci

Uložení označení „přečteno“

důležitost: 5

Máme pole zpráv:

let zprávy = [
  {text: "Ahoj", od: "Jan"},
  {text: "Jak se máš?", od: "Jan"},
  {text: "Brzy nashle", od: "Alice"}
];

Váš kód k němu může přistupovat, ale zprávy spravuje kód někoho jiného. Tento kód pravidelně přidává nové zprávy a odebírá staré. Vy neznáte přesný okamžik, kdy se to stane.

Kterou datovou strukturu nyní můžete použít k uložení informace, že zpráva „byla přečtena“? Struktura musí být vybavena tak, aby pro zadaný objekt zprávy vydala odpověď na otázku „byla zpráva přečtena?“.

P.S. Když je zpráva odstraněna z pole zprávy, měla by zmizet i z vaší struktury.

P.P.S. Objekty zpráv bychom neměli modifikovat a přidávat do nich naše vlastnosti. Protože je spravuje kód někoho jiného, mohlo by to vést k nežádoucím důsledkům.

Uložme přečtené zprávy do WeakSet:

let zprávy = [
  {text: "Ahoj", od: "Jan"},
  {text: "Jak se máš?", od: "Jan"},
  {text: "Brzy nashle", od: "Alice"}
];

let přečtenéZprávy = new WeakSet();

// dvě zprávy byly přečteny
přečtenéZprávy.add(zprávy[0]);
přečtenéZprávy.add(zprávy[1]);
// přečtenéZprávy obsahuje 2 prvky

// ...znovu přečteme první zprávu!
přečtenéZprávy.add(zprávy[0]);
// přečtenéZprávy stále obsahuje 2 unikátní prvky

// odpověď: byla zpráva s indexem 0 přečtena?
alert("Zpráva 0 přečtena: " + přečtenéZprávy.has(zprávy[0])); // true

zprávy.shift();
// nyní přečtenéZprávy obsahuje 1 prvek (technicky může být paměť vyčištěna později)

WeakSet nám umožňuje uložit množinu zpráv a snadno ověřovat, zda v ní zpráva existuje.

Automaticky se vyčistí. Nevýhodou je, že nad ní nemůžeme iterovat, nemůžeme získat „všechny přečtené zprávy“ přímo z ní. Můžeme to však udělat iterací nad všemi zprávami a filtrováním těch, které jsou v této množině.

Jiným řešením by bylo přidání vlastnosti, např. zpráva.jePřečtena=true, do zprávy poté, co bude přečtena. Pokud objekty zpráv spravuje jiný kód, obecně se to nedoporučuje, ale můžeme se vyhnout konfliktům použitím symbolické vlastnosti.

Třeba takto:

// symbolickou vlastnost zná pouze náš kód
let jePřečtena = Symbol("jePřečtena");
zprávy[0][jePřečtena] = true;

Nyní kód třetí strany naši přidanou vlastnost neuvidí.

Přestože symboly mohou snížit pravděpodobnost problémů, z architektonického hlediska je lepší použít WeakSet.