ტაიმერები და კონტექსტის დაკარგვა 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-ით. თუმცა, ღილაკზე დაწკაპუნებისას
საერთოდ არაფერი ხდება. გამასწორეთ ავტორის შეცდომა
კოდში. დაწერეთ ტექსტი, რომელშიც თქვენ
მისცემთ ახსნანს კოდის ავტორს, რატომ წარმოიშვა
მისი შეცდომა.