Timery i utrata kontekstu w JavaScript

Przy użyciu timerów w procedurach obsługi zdarzeń czekają na nas problemy z utratą kontekstu. Spójrzmy na przykład.

Załóżmy, że mamy pole input:

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

Załóżmy, że po kliknięciu na to pole input uruchomi się anonimowa funkcja i wewnątrz tej funkcji wystartuje timer, który co sekundę wypisze coś w konsoli:

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

elem.addEventListener('click', function() {
  setInterval(function() {
    console.log('!!!'); // coś wypisujemy w konsoli
  }, 1000);
});

Na razie wszystko działa poprawnie. Ale załóżmy teraz, że chcemy wypisać w konsoli value naszego pola input - czeka nas niespodzianka: w konsoli będzie wypisywane undefined:

javascriptelem.addEventListener('click', function() {
  setInterval(function() {
    console.log(this.value); // będzie wypisywane undefined
  }, 1000);
});

Chodzi o to, że otrzymujemy funkcję w funkcji: jest zewnętrzna funkcja anonimowa, która jest wywoływana po kliknięciu i wewnętrzna funkcja anonimowa, którą uruchamia timer. W funkcji zewnętrznej this wskazuje na pole input, ale we wewnętrznej - nie. Mamy do czynienia z utratą kontekstu.

Dlaczego wypisywane jest undefined, a nie wyskakuje błąd w konsoli, jak to miało miejsce w poprzednich lekcjach? Ponieważ this wewnątrz funkcji, wywoływanej przez setInterval, wskazuje na window.

Oznacza to, że próbujemy odczytać właściwość value obiektu window, tak o: window.value, a takiej właściwości w nim nie ma i otrzymujemy undefined (nie błąd).

Poprawmy problem wprowadzając self:

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

Załóżmy, że dany jest taki 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);
});

Autor kodu chciał, aby po naciśnięciu przycisku, wartość tego przycisku co sekundę zwiększała się o 1. Jednak po naciśnięciu przycisku nic się nie dzieje. Popraw błąd autora kodu. Napisz tekst, w którym dasz wyjaśnienie autorowi kodu, dlaczego powstał jego błąd.