⊗jsPmTrTCL 451 of 505 menu

Таймери и загуба на контекст в JavaScript

При използване на таймери в манипулатори на събития ни очакват проблеми със загуба на контекст. Нека разгледаме пример.

Да предположим, че имаме input поле:

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

Да предположим, че при клик върху това input поле се изпълнява анонимна функция и вътре в тази функция се стартира таймер, който всяка секунда извежда нещо в конзолата:

let elem = document.querySelector('#elem'); elem.addEventListener('click', function() { setInterval(function() { console.log('!!!'); // извеждаме нещо в конзолата }, 1000); });

Дотук всичко работи правилно. Но сега да предположим, че искаме да извеждаме в конзолата value на нашия input - ни очаква изненада: в конзолата ще се извежда undefined:

elem.addEventListener('click', function() { setInterval(function() { console.log(this.value); // ще се извежда undefined }, 1000); });

Цялата работа е в това, че се получава функция във функция: има външна анонимна функция, която се извиква при клик и вътрешна анонимна функция, която се стартира от таймера. Във външната функция this сочи към input полето, но във вътрешната - не. Имаме загуба на контекст.

Защо се извежда undefined, а не се появява грешка в конзолата, както беше в предишните уроци? Защото this във функцията, извикана чрез setInterval, сочи към window.

Това означава, че се опитваме да прочетем свойството value на обекта window, ето така: window.value, а такова свойство в него няма, и получаваме undefined (не грешка).

Нека поправим проблема чрез въвеждане на self:

elem.addEventListener('click', function() { let self = this; setInterval(function() { console.log(self.value); }, 1000); });

Даден е следният код:

<input type="button" id="elem" value="1"> let elem = document.querySelector('#elem'); elem.addEventListener('click', function() { setInterval(function() { this.value = Number(elem.value) + 1; }, 1000); });

Авторът на кода е искал при натискане на бутона, стойността на този бутон да се увеличава всяка секунда с 1. Обаче, при натискане на бутона изобщо нищо не се случва. Поправете грешката в кода на автора. Напишете текст, в който дадете обяснение на автора на кода, защо е възникнала неговата грешка.

Български
AfrikaansAzərbaycanবাংলাБеларускаяČeštinaDanskDeutschΕλληνικάEnglishEspañolEestiSuomiFrançaisहिन्दीMagyarՀայերենIndonesiaItaliano日本語ქართულიҚазақ한국어КыргызчаLietuviųLatviešuМакедонскиMelayuမြန်မာNederlandsNorskPolskiPortuguêsRomânăРусскийසිංහලSlovenčinaSlovenščinaShqipСрпскиSrpskiSvenskaKiswahiliТоҷикӣไทยTürkmenTürkçeЎзбекOʻzbekTiếng Việt
Ние използваме бисквитки за работата на сайта, анализ и персонализация. Обработката на данни се извършва в съответствие с Политика за поверителност.
приемам всички настройки отхвърляне