JavaScript-da taymerlar va kontekst yo'qotish
Taymerlardan foydalanganda hodisalar ishlovchilarida kontekst yo'qotilishi muammolari bilan duch kelishimiz mumkin. Keling, buni misol orqali ko'rib chiqaylik.
Faraz qilaylik, bizda bir input maydoni mavjud:
<input id="elem" value="text">
Faraz qilaylik, ushbu input maydoniga bosilganda anonim funksiya ishga tushsin va shu funksiya ichida har soniyada nimanidir konsolga chiqaradigan taymer ishga tushsin:
let elem = document.querySelector('#elem');
elem.addEventListener('click', function() {
setInterval(function() {
console.log('!!!'); // nimanidir konsolga chiqaramiz
}, 1000);
});
Hozircha hamma narsa to'g'ri ishlamoqda. Lekin endi
biz inputning value qiymatini
konsolga chiqarishni xohlasak - bizni kutilmagan voqea kutmoqda: konsolga
undefined chiqadi:
elem.addEventListener('click', function() {
setInterval(function() {
console.log(this.value); // undefined chiqadi
}, 1000);
});
Muammo shundaki, bizda funksiya ichida funksiya
paydo bo'ladi: tashqi anonim funksiya mavjud bo'lib,
u bosish orqali chaqiriladi va ichki
anonim funksiya mavjud bo'lib, uni taymer ishga tushiradi.
Tashqi funksiyada this
inputga ishora qiladi, lekin ichki funksiyada - qilmaydi. Kontekst
yo'qolishi yuz beradi.
Nima uchun undefined chiqadi,
oldingi darslardagi kabi konsolda xatolik
paydo bo'lmaydi? Chunki setInterval orqali
chaqiriladigan funksiya ichidagi this
window obyektiga ishora qiladi.
Bu shuni anglatadiki, biz window obyektidan
value xususiyatini o'qishga harakat qilyapmiz, shunday: window.value,
lekin unda bunday xususiyat yo'q va biz
undefined olamiz (xatolik emas).
Muammoni self ni joriy qilish orqali tuzatamiz:
elem.addEventListener('click', function() {
let self = this;
setInterval(function() {
console.log(self.value);
}, 1000);
});
Faraz qilaylik, quyidagi kod berilgan:
<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);
});
Kod muallifi tugmacha bosilganda,
ushbu tugmachaning qiymati har soniyada 1 ga oshishini
xohlagan.
Biroq, tugmachani bosganda
hech narsa bo'lmaydi. Muallif kodidagi xatoni tuzating.
Kod muallifiga uning xatosi nimadan kelib chiqqanligi haqida
izoh beradigan matn yozing.