Timers och kontextförlust i JavaScript

När man använder timers i händelsehanterare väntar problem med kontextförlust på oss. Låt oss titta på ett exempel.

Låt oss säga att vi har en input:

html<input id="elem" value="text">

Låt oss säga att vid ett klick på denna input triggas en anonym funktion och inuti denna funktion startas en timer som varje sekund skriver ut något i konsolen:

javascriptlet elem = document.querySelector('#elem');

elem.addEventListener('click', function() {
  setInterval(function() {
    console.log('!!!'); // skriver ut något i konsolen
  }, 1000);
});

Än så länge fungerar allt korrekt. Men låt oss nu säga att vi vill skriva ut value från vår input i konsolen - vi väntar en överraskning: i konsolen kommer undefined att skrivas ut:

javascriptelem.addEventListener('click', function() {
  setInterval(function() {
    console.log(this.value); // kommer att skriva ut undefined
  }, 1000);
});

Hela saken är att vi får en funktion i en funktion: det finns en extern anonym funktion, som anropas vid klick, och en intern anonym funktion, som triggas av timern. I den externa funktionen pekar this på input, men i den interna - inte. Det finns en kontextförlust.

Varför skrivs undefined ut, och inte ett fel i konsolen, som det var i tidigare lektioner? Eftersom this inuti funktionen som anropas via setInterval, pekar på window.

Det betyder att vi försöker läsa egenskapen value från objektet window, så här: window.value, och det finns ingen sådan egenskap i det, och vi får undefined (inget fel).

Låt oss åtgärda problemet genom att introducera self:

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

Låt oss säga att vi har denna 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);
});

Kodens författare ville att när knappen klickades, ska värdet på denna knapp ökas med 1 varje sekund. Men när man klickar på knappen händer ingenting alls. Råtta författarens fel. Skriv en text där du ger en förklaring till kodens författare om varför felet uppstod.