Timer dan Kehilangan Konteks dalam JavaScript
Saat menggunakan timer dalam penangan peristiwa, kita menghadapi masalah kehilangan konteks. Mari kita lihat contohnya.
Misalkan kita memiliki sebuah input:
<input id="elem" value="text">
Misalkan saat klik pada input ini, sebuah fungsi anonim akan dijalankan dan di dalam fungsi tersebut sebuah timer akan dimulai, yang setiap detik mencetak sesuatu ke konsol:
let elem = document.querySelector('#elem');
elem.addEventListener('click', function() {
setInterval(function() {
console.log('!!!'); // mencetak sesuatu ke konsol
}, 1000);
});
Sejauh ini berfungsi dengan benar. Tapi sekarang misalkan
kita ingin mencetak value
input kita ke konsol - kita akan mendapat kejutan: yang tercetak
di konsol adalah undefined:
elem.addEventListener('click', function() {
setInterval(function() {
console.log(this.value); // akan mencetak undefined
}, 1000);
});
Masalahnya adalah kita memiliki fungsi
dalam fungsi: ada fungsi anonim luar,
yang dipanggil saat klik, dan fungsi anonim
dalam, yang dijalankan oleh timer.
Pada fungsi luar, this menunjuk
pada input, tetapi pada fungsi dalam - tidak. Terjadi
kehilangan konteks.
Mengapa yang tercetak adalah undefined, dan tidak muncul
error di konsol, seperti pada pelajaran-pelajaran
sebelumnya? Karena this di dalam fungsi,
yang dipanggil melalui setInterval, menunjuk
pada window.
Ini berarti kita mencoba membaca properti
value dari objek window, seperti ini: window.value,
dan properti seperti itu tidak ada di dalamnya, sehingga kita mendapatkan
undefined (bukan error).
Mari perbaiki masalah dengan memperkenalkan self:
elem.addEventListener('click', function() {
let self = this;
setInterval(function() {
console.log(self.value);
}, 1000);
});
Misalkan diberikan kode seperti ini:
<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);
});
Penulis kode ingin agar saat tombol ditekan,
nilai tombol tersebut setiap detik bertambah
sebesar 1. Namun, saat tombol ditekan
tidak terjadi apa-apa. Perbaiki kesalahan
penulis kode. Tuliskan teks, di mana Anda
memberikan penjelasan kepada penulis kode, mengapa kesalahannya
terjadi.