Kronometrat dhe Humbja e Kontekstit në JavaScript
Gjatë përdorimit të kronometrave në përpunuesit e ngjarjeve, ne përballemi me probleme të humbjes së kontekstit. Le të shohim një shembull.
Le të themi se kemi një input:
<input id="elem" value="text">
Le të themi se me klikim në këtë input do të ekzekutohet një funksion anonim dhe brenda këtij funksioni do të niset një kronometër, i cili çdo sekondë do të shfaqë diçka në konsol:
let elem = document.querySelector('#elem');
elem.addEventListener('click', function() {
setInterval(function() {
console.log('!!!'); // shfaqim diçka në konsol
}, 1000);
});
Deri tani gjithçka funksionon si duhet. Por le të themi tani
që duam të shfaqim në konsol value
të input-it tonë - ne do të përballemi me një surprizë: në konsol
do të shfaqet undefined:
elem.addEventListener('click', function() {
setInterval(function() {
console.log(this.value); // do të shfaqet undefined
}, 1000);
});
E gjitha ka të bëjë me faktin se kemi një funksion
brenda një funksioni: ka një funksion të jashtëm anonim,
që thirret me klikim dhe një funksion
të brendshëm anonim, të cilin e nis kronometri.
Në funksionin e jashtëm this tregon
te input-i, por në atë të brendshëm - jo. Ka vend
humbje konteksti.
Pse shfaqet undefined, dhe nuk shfaqet
gabim në konsol, siç ndodhi në mësimet e mëparshme?
Sepse this brenda funksionit,
që thirret përmes setInterval, tregon
te window.
Kjo do të thotë se ne po përpiqemi të lexojmë vetinë
value nga objekti window, kështu: window.value,
dhe meqë një veti e tillë nuk ekziston në të, marrim
undefined (jo gabim).
Le ta rregullojmë problemin duke futur self:
elem.addEventListener('click', function() {
let self = this;
setInterval(function() {
console.log(self.value);
}, 1000);
});
Le të themi se është dhënë ky kod:
<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);
});
Autori i kodit dëshironte që me shtypjen e butonit,
vlera e këtij butoni të rritej çdo sekondë
me 1. Megjithatë, me shtypjen e butonit
nuk ndodh absolutisht asgjë. Korrigjoni gabimin
e autorit të kodit. Shkruani një tekst, në të cilin ju
do t'i jepni një shpjegim autorit të kodit, pse u shfaq
gabimi i tij.