Запіс на курсы па HTML, CSS, JavaScript, PHP, Python, фрэймворкам і CMS,
а таксама: дапамога ў пошуку працы і заказаў, стажыроўка на рэальных праектах→
⊗jsPmTrTCL 451 of 505 menu

Таймеры і страта кантэксту ў JavaScript

Пры выкарыстанні таймераў у апрацоўшчыках падзей нас падпяшаюць праблемы са стратай кантэксту. Давайце паглядзім на прыкладзе.

Хай у нас ёсць інпут:

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

Хай па кліку на гэты інпут спрацуе ананімная функцыя і ўнутры гэтай функцыі запусціцца таймер, кожную секунду які выводзіць што-небудзь у кансоль:

let elem = document.querySelector('#elem'); elem.addEventListener('click', function() { setInterval(function() { console.log('!!!'); // што-небудзь выводзім у кансоль }, 1000); });

Пакуль усё працуе правільна. Але хай цяпер мы хочам выводзіць у кансоль value нашага інпута - нас чакае сюрпрыз: у кансоль будзе выводзіцца undefined:

elem.addEventListener('click', function() { setInterval(function() { console.log(this.value); // будзе выводзіцца undefined }, 1000); });

Уся справа ў тым, што ў нас атрымліваецца функцыя ў функцыі: ёсць знешняя ананімная функцыя, якая выклікаецца па кліку і ўнутраная ананімная функцыя, якую запускае таймер. У знешняй функцыі this паказвае на інпут, але ва ўнутранай - не. Мае месца страта кантэксту.

Чаму выводзіцца 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. Аднак, па націсканні на кнопку наогул нічога не адбываецца. Выправіце памылку аўтара кода. Напішыце тэкст, у якім вы дасце тлумачэнне аўтару кода, чаму ўзнікла яго памылка.

byenru