JavaScript'te Bağlam Kaybı

Bir fonksiyonun içinde başka bir fonksiyonumuz olduğunu varsayalım. Dıştaki fonksiyona parent (ebeveyn), içteki fonksiyona ise child (çocuk) diyelim:

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

Önceki derslerden biliyorsunuz ki, dış fonksiyonda bir değişken tanımlarsanız - bu değişkene iç fonksiyondan da erişilebilir:

javascriptfunction parent() {
  let str = 'abcde';
  
  function child() {
    console.log(str); // 'abcde' yazdıracak
  }
  child(); // iç fonksiyonu çağırıyoruz
}

parent(); // dış fonksiyonu çağırıyoruz

Ancak bir nüans var: iç fonksiyon, dış fonksiyonun tüm değişkenlerine erişebilir, ancak this değerine erişemez. Yani: eğer dış fonksiyon bir DOM elemanına bağlıysa, o fonksiyonun içindeki this bu elemanı gösterecektir, ancak iç fonksiyondaki this - göstermeyecek!

Peki iç fonksiyondaki this neyi gösterecek? Cevap: undefined olacak (strict modda), çünkü fonksiyon hiçbir şeye bağlı değil.

Pratikte test edelim. Bir input elemanımız olsun:

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

Bu inputa, odak kaybedildiğinde tetiklenecek olan parent fonksiyonunu bağlayalım:

javascript"use strict";

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

// Odak kaybedildiğinde çağrılacak:
function parent() {
  // burada bir kod olacak
  
  function child() {
    // burada bir kod olacak
  }
  child(); // alt fonksiyonu çağırıyoruz
}

Şimdi this değerinin içeriğini iki yerde konsola yazdıralım: parent fonksiyonunun içinde ve child fonksiyonunun içinde:

javascript"use strict";

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

function parent() {
  console.log(this); // inputumuzun referansını yazdıracak
  
  function child() {
    console.log(this); // undefined yazdıracak
  }
  child();
}

Bu kodu çalıştırın, inputun odağını kaybettirin ve konsola bakın - göreceksiniz ki ilk console.log konsola inputumuzun referansını yazdıracak, ikincisi ise sadece undefined yazdıracak. this'in beklenmedik bir şekilde ihtiyacımız olan şeyi göstermediği bu duruma, bağlam kaybı denir.

Задание 1

Şimdi her iki fonksiyonda da inputun value değerini yazdırdığımızı varsayalım. Yorum satırlarıyla işaretlenmiş kod satırlarında ne yazdırılacağını belirleyin:

javascript"use strict";

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

function parent() {
  console.log(this.value); // ne yazdıracak?
  
  function child() {
    console.log(this.value); // ne yazdıracak?
  }
  child();
}