Opravte funkci, která ztrácí „this“
Volání zeptejSeNaHeslo() v následujícím kódu by mělo zkontrolovat heslo a pak podle toho, jaká je odpověď, zavolat uživatel.přihlášeníOK/přihlášeníSelhalo.
Vede však k chybě. Proč?
Opravte zvýrazněný řádek tak, aby všechno začalo fungovat správně (ostatní řádky neměňte).
function zeptejSeNaHeslo(ok, selhal) {
let heslo = prompt("Heslo?", '');
if (heslo == "rockstar") ok();
else selhal();
}
let uživatel = {
jméno: 'Jan',
přihlášeníOK() {
alert(`${this.jméno} přihlášen`);
},
přihlášeníSelhalo() {
alert(`${this.jméno} se nedokázal přihlásit`);
},
};
zeptejSeNaHeslo(uživatel.přihlášeníOK, uživatel.přihlášeníSelhalo);
Chyba nastane proto, že funkce zeptejSeNaHeslo obdrží funkce přihlášeníOK/přihlášeníSelhalo bez objektu.
Když je zavolá, přirozeně předpokládají this=undefined.
Navažme kontext funkcí bind:
function zeptejSeNaHeslo(ok, selhal) {
let heslo = prompt("Heslo?", '');
if (heslo == "rockstar") ok();
else selhal();
}
let uživatel = {
jméno: 'Jan',
přihlášeníOK() {
alert(`${this.jméno} se přihlásil`);
},
přihlášeníSelhalo() {
alert(`${this.jméno} se nedokázal přihlásit`);
},
};
zeptejSeNaHeslo(uživatel.přihlášeníOK.bind(uživatel), uživatel.přihlášeníSelhalo.bind(uživatel));
Teď to funguje.
Alternativní řešení by mohlo být:
//...
zeptejSeNaHeslo(() => uživatel.přihlášeníOK(), () => uživatel.přihlášeníSelhalo());
Obvykle to také funguje a vypadá dobře.
Je to však méně spolehlivé ve složitějších situacích, kdy se proměnná uživatel může změnit po volání zeptejSeNaHeslo, ale před odpovědí návštěvníka a voláním () => uživatel.přihlášeníOK().