Թայմերներ և կոնտեքստի կորուստ 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-ով։ Սակայն, կոճակի վրա սեղմելիս ընդհանրապես ոչինչ չի կատարվում։ Ուղղեք հեղինակի սխալը։ Գրեք տեքստ, որում դուք բացատրություն կտաք կոդի հեղինակին, թե ինչու առաջացավ նրա սխալը։