ტაიმერები და კონტექსტის დაკარგვა JavaScript-ში

ტაიმერების გამოყენებისას მოვლენების დამმუშავებლებში გველის კონტექსტის დაკარგვის პრობლემა. მოდით შევხედოთ მაგალითს.

დავუშვათ, გვაქვს ინფუთი:

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

დავუშვათ, ამ ინფუთზე დაწკაპუნებაზე გაეშვება ანონიმური ფუნქცია და ამ ფუნქციის შიგნით გაეშვება ტაიმერი, რომელიც ყოველ წამს დაბეჭდავს რაიმეს კონსოლში:

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

elem.addEventListener('click', function() {
  setInterval(function() {
    console.log('!!!'); // რაიმეს ვბეჭდავთ კონსოლში
  }, 1000);
});

ჯერჯერობით ყველაფერი სწორად მუშაობს. მაგრამ დავუშვათ ახლა გვსურს კონსოლში გამოვიტანოთ value ჩვენი ინფუთის - გველის სიურპრიზი: კონსოლში გამოიტანს undefined-ს:

javascriptelem.addEventListener('click', function() {
  setInterval(function() {
    console.log(this.value); // გამოიტანს undefined-ს
  }, 1000);
});

მთელი საქმე იმაშია, რომ ჩვენ გვაქვს ფუნქცია ფუნქციაში: არის გარე ანონიმური ფუნქცია, რომელიც იწყება დაწკაპუნებით და შიდა ანონიმური ფუნქცია, რომელსაც ტაიმერი აწყებს. გარე ფუნქციაში this მიუთითებს ინფუთზე, მაგრამ შიდაში - არა. აქვს ადგილი კონტექსტის დაკარგვა.

რატომ გამოიტანს undefined-ს და არ გამოიწვევს შეცდომას კონსოლში, როგორც ეს იყო წინა გაკვეთილებში? იმიტომ, რომ this შიდა ფუნქციაში, რომელიც იწყება setInterval-ის მეშვეობით, მიუთითებს window-ზე.

ეს ნიშნავს, რომ ჩვენ ვცდილობთ წავიკითხოთ value თვისება window ობიექტიდან, ასე: window.value, და მასში ასეთი თვისება არ არის, და ჩვენ ვიღებთ undefined-ს (არა შეცდომას).

გამოვასწოროთ პრობლემა self-ის შემოღებით:

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

დავუშვათ მოცემულია ასეთი კოდი:

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);
});

კოდის ავტორს სურდა, რომ ღილაკზე დაწკაპუნებისას, ამ ღილაკის მნიშვნელობა ყოველ წამში გაეზარდა 1-ით. თუმცა, ღილაკზე დაწკაპუნებისას საერთოდ არაფერი ხდება. გამასწორეთ ავტორის შეცდომა კოდში. დაწერეთ ტექსტი, რომელშიც თქვენ მისცემთ ახსნანს კოდის ავტორს, რატომ წარმოიშვა მისი შეცდომა.