Pozorovatelný objekt
Vytvořte funkci učiňPozorovatelným(cíl), která „učiní objekt pozorovatelným“ tím, že vrátí proxy.
Mělo by to fungovat takto:
function učiňPozorovatelným(cíl) {
/* váš kód */
}
let uživatel = {};
uživatel = učiňPozorovatelným(uživatel);
uživatel.pozoruj((klíč, hodnota) => {
alert(`SET ${klíč}=${hodnota}`);
});
uživatel.jméno = "Jan"; // oznámí: SET jméno=Jan
Jinými slovy, objekt vrácený funkcí učiňPozorovatelným je stejný jako původní, ale navíc obsahuje metodu pozoruj(handler), která nastaví funkci handler tak, aby byla volána při každé změně vlastnosti.
Kdykoli se změní některá vlastnost, je zavolán handler(klíč, hodnota) s jejím názvem a hodnotou.
P.S. V této úloze se postarejte jen o zápis do vlastnosti. Ostatní operace mohou být implementovány podobně.
Řešení se skládá ze dvou částí:
- Kdykoli je zavoláno
.pozoruj(handler), musíme si handler někde pamatovat, abychom jej mohli volat později. Handlery si můžeme ukládat rovnou do objektu a jako klíč vlastnosti použít náš symbol. - Potřebujeme proxy s pastí
set, která v případě jakékoli změny zavolá handlery.
let handlery = Symbol('handlery');
function učiňPozorovatelným(cíl) {
// 1. Inicializace skladu handlerů
cíl[handlery] = [];
// Uložíme funkci handleru do pole pro budoucí volání
cíl.pozoruj = function(handler) {
this[handlery].push(handler);
};
// 2. Vytvoříme proxy pro zpracování změn
return new Proxy(cíl, {
set(cíl, vlastnost, hodnota, příjemce) {
let úspěch = Reflect.set(...arguments); // předáme operaci objektu
if (úspěch) { // pokud při nastavování vlastnosti nedošlo k chybě,
// zavoláme všechny handlery
cíl[handlery].forEach(handler => handler(vlastnost, hodnota));
}
return úspěch;
}
});
}
let uživatel = {};
uživatel = učiňPozorovatelným(uživatel);
uživatel.pozoruj((klíč, hodnota) => {
alert(`SET ${klíč}=${hodnota}`);
});
uživatel.jméno = "Jan";