კონტექსტის დაკარგვა JavaScript-ში
დავუშვათ, გვაქვს ფუნქცია ფუნქციის შიგნით. გარე
ფუნქციას დავარქვათ parent, ხოლო
შიდა ფუნქციას - child:
function parent() {
function child() {
}
}
წინა გაკვეთილებიდან იცით, რომ თუ რაიმე ცვლადს გარე ფუნქციაში განსაზღვრავთ - ის შიდა ფუნქციაში იქნება ხელმისაწვდომი:
function parent() {
let str = 'abcde';
function child() {
console.log(str); // გამოიტანს 'abcde'
}
child(); // ვიძახებთ შიდა ფუნქციას
}
parent(); // ვიძახებთ გარე ფუნქციას
თუმცა, არის ნიუანსი: შიდა ფუნქციას აქვს
წვდომა გარე ფუნქციის ყველა ცვლადზე, მაგრამ მას
არ აქვს წვდომა this-ზე. ანუ: თუ
გარე ფუნქცია მიბმულია რაიმე DOM
ელემენტთან, მაშინ მასში this მიუთითებს
ამ ელემენტზე, მაგრამ შიდა ფუნქციაში this - არა!
მაშინ რაზე მიუთითებს შიდა ფუნქციაში this?
პასუხი: ის იქნება
undefined (სტრიქონული რეჟიმში),
რადგან ფუნქცია არსად არის მიბმული.
პრაქტიკაში გადავამოწმოთ. დავუშვათ, გვაქვს ინფუთი:
<input id="elem" value="text">
მივაბათ ამ ინფუთს ფუნქცია parent,
რომელიც გაეშვება ინფუთის ფოკუსის დაკარგვისას:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
// გაეშვება ფოკუსის დაკარგვისას:
function parent() {
// აქ იქნება რაიმე კოდი
function child() {
// აქ იქნება რაიმე კოდი
}
child(); // ვიძახებთ შვილობილ ფუნქციას
}
გამოვიტანოთ this-ის შიგთავსი
კონსოლში ორ ადგილას: parent
ფუნქციის შიგნით და child ფუნქციის შიგნით:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this); // გამოიტანს ჩვენი ინფუთის მისამართს
function child() {
console.log(this); // გამოიტანს undefined
}
child();
}
გაუშვით ეს კოდი, დაკარგეთ ინფუთის ფოკუსი
და შეხედეთ კონსოლს - დაინახავთ, რომ
პირველი console.log კონსოლში
გამოიტანს ჩვენი ინფუთის მისამართს, ხოლო მეორე - უბრალოდ undefined-ს.
ასეთ სიტუაციას, როდესაც this ჩვენთვის მოულოდნელად
არ მიუთითებს იმაზე, რაც ჩვენ
გვჭირდება, ეწოდება კონტექსტის დაკარგვა.
დავუშვათ, ახლა ერთსა და მეორე ფუნქციაში
ვიღებთ ინფუთის value-ს. დაადგინეთ,
რა გამოიყვანს კოდის იმ სტრიქონებში, რომლებიც
მონიშნულია კომენტარებით:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this.value); // რა გამოიტანს?
function child() {
console.log(this.value); // რა გამოიტანს?
}
child();
}