Тajмери и губитак контекста у 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. Међутим, при притиску на дугме
се уопште ништа не дешава. Исправите грешку
аутора кода. Напишите текст у ком ћете
дати објашњење аутору кода, зашто је настала
његова грешка.