Időzítők és a kontextus elvesztése a JavaScriptben
Az időzítők eseménykezelőkben való használatakor kontextusvesztési problémák leselkednek ránk. Nézzük meg ezt egy példán keresztül.
Tegyük fel, hogy van egy bemeneti mezőnk:
<input id="elem" value="text">
Tegyük fel, hogy egy kattintásra ez a bemeneti mező egy anonim függvényt aktivál, és ezen függvényen belül elindul egy időzítő, amely másodpercenként kiír valamit a konzolra:
let elem = document.querySelector('#elem');
elem.addEventListener('click', function() {
setInterval(function() {
console.log('!!!'); // kiírunk valamit a konzolra
}, 1000);
});
Eddig minden helyesen működik. De tegyük fel most, hogy
a bemeneti mező value értékét szeretnénk
kiírni a konzolra - egy meglepetés ériz ránk: a konzolba
undefined fog kiíródni:
elem.addEventListener('click', function() {
setInterval(function() {
console.log(this.value); // undefined fog kiíródni
}, 1000);
});
Az egész azon múlik, hogy egy függvényt kapunk egy függvényben:
van egy külső anonim függvény,
amely kattintásra hívódik meg, és egy belső
anonim függvény, amelyet az időzítő indít el.
A külső függvényben a this a bemeneti mezőre mutat,
de a belsőben - nem. Kontextusvesztés következik be.
Miért jelenik meg undefined, és nem jelenik meg
egy hiba a konzolban, mint az előző leckékben?
Mert a this azon függvényen belül,
amelyet setInterval-lel hívunk meg, a
window objektumra mutat.
Ez azt jelenti, hogy megpróbáljuk elolvasni a value tulajdonságot
a window objektumtól, így: window.value,
de ilyen tulajdonság nincs benne, és így
undefined-et kapunk (nem hibát).
Javítsuk a problémát egy self változó bevezetésével:
elem.addEventListener('click', function() {
let self = this;
setInterval(function() {
console.log(self.value);
}, 1000);
});
Tegyük fel, hogy a következő kód adott:
<input type="button" id="elem" value="1">
let elem = document.querySelector('#elem');
elem.addEventListener('click', function() {
setInterval(function() {
this.value = Number(elem.value) + 1;
}, 1000);
});
A kód szerzője azt szerette volna, hogy a gombra kattintáskor
a gomb értéke másodpercenként 1-gyel növekedjen.
Azonban a gombra kattintáskor
egyáltalán semmi sem történik. Javítsa ki a kód
szerzőjének hibáját. Írjon egy szöveget, amelyben
magyarázatot ad a kód szerzőjének, hogy miért
következett be a hibája.