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:

html<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:

javascriptlet 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:

javascriptelem.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:

javascriptelem.addEventListener('click', function() {
  let self = this;
  
  setInterval(function() {
    console.log(self.value);
  }, 1000);
});
Задание 1

Le të themi se është dhënë ky kod:

html<input type="button" id="elem" value="1">
javascriptlet 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.