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:
function 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:
function 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:
<input id="elem" value="text">
Bu inputa, odak kaybedildiğinde tetiklenecek olan parent
fonksiyonunu bağlayalım:
"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:
"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.
Ş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:
"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();
}