კონტექსტის დაკარგვა JavaScript-ში

დავუშვათ, გვაქვს ფუნქცია ფუნქციის შიგნით. გარე ფუნქციას დავარქვათ parent, ხოლო შიდა ფუნქციას - child:

javascriptfunction parent() {
  function child() {
    
  }
}

წინა გაკვეთილებიდან იცით, რომ თუ რაიმე ცვლადს გარე ფუნქციაში განსაზღვრავთ - ის შიდა ფუნქციაში იქნება ხელმისაწვდომი:

javascriptfunction parent() {
  let str = 'abcde';
  
  function child() {
    console.log(str); // გამოიტანს 'abcde'
  }
  child(); // ვიძახებთ შიდა ფუნქციას
}

parent(); // ვიძახებთ გარე ფუნქციას

თუმცა, არის ნიუანსი: შიდა ფუნქციას აქვს წვდომა გარე ფუნქციის ყველა ცვლადზე, მაგრამ მას არ აქვს წვდომა this-ზე. ანუ: თუ გარე ფუნქცია მიბმულია რაიმე DOM ელემენტთან, მაშინ მასში this მიუთითებს ამ ელემენტზე, მაგრამ შიდა ფუნქციაში this - არა!

მაშინ რაზე მიუთითებს შიდა ფუნქციაში this? პასუხი: ის იქნება undefined (სტრიქონული რეჟიმში), რადგან ფუნქცია არსად არის მიბმული.

პრაქტიკაში გადავამოწმოთ. დავუშვათ, გვაქვს ინფუთი:

html<input id="elem" value="text">

მივაბათ ამ ინფუთს ფუნქცია parent, რომელიც გაეშვება ინფუთის ფოკუსის დაკარგვისას:

javascript"use strict";

let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);

// გაეშვება ფოკუსის დაკარგვისას:
function parent() {
  // აქ იქნება რაიმე კოდი
  
  function child() {
    // აქ იქნება რაიმე კოდი
  }
  child(); // ვიძახებთ შვილობილ ფუნქციას
}

გამოვიტანოთ this-ის შიგთავსი კონსოლში ორ ადგილას: parent ფუნქციის შიგნით და child ფუნქციის შიგნით:

javascript"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 ჩვენთვის მოულოდნელად არ მიუთითებს იმაზე, რაც ჩვენ გვჭირდება, ეწოდება კონტექსტის დაკარგვა.

Задание 1

დავუშვათ, ახლა ერთსა და მეორე ფუნქციაში ვიღებთ ინფუთის value-ს. დაადგინეთ, რა გამოიყვანს კოდის იმ სტრიქონებში, რომლებიც მონიშნულია კომენტარებით:

javascript"use strict";

let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);

function parent() {
  console.log(this.value); // რა გამოიტანს?
  
  function child() {
    console.log(this.value); // რა გამოიტანს?
  }
  child();
}