JavaScript-də kontekst itkisi
Tutaq ki, bizim funksiya içində funksiyamız var. Gəlin
xarici funksiyanı parent, daxili funksiyanı isə
child adlandıraq:
function parent() {
function child() {
}
}
Əvvəlki dərslərdən bilirsiniz ki, əgər xarici funksiyada hər hansı bir dəyişən təyin etsəniz - o, daxili funksiyada əlçatan olacaq:
function parent() {
let str = 'abcde';
function child() {
console.log(str); // 'abcde' çap edəcək
}
child(); // daxili funksiyanı çağırırıq
}
parent(); // xarici funksiyanı çağırırıq
Lakin bir nüans var: daxili funksiya xarici funksiyanın
bütün dəyişənlərinə çıxışı var, lakin this-ə çıxışı yoxdur.
Yəni: əgər xarici funksiya hansısa DOM elementinə bağlıdırsa,
onda onun içindəki this həmin elementi göstərəcək,
lakin daxili funksiyanın this-i göstərməyəcək!
Bəs daxili funksiyanın this-i nəyə işarə edəcək?
Cavab: o, undefined-ə bərabər olacaq (ciddi rejimdə),
çünki funksiya heç nəyə bağlı deyil.
Gəlin praktikada yoxlayaq. Tutaq ki, bizə input verilib:
<input id="elem" value="text">
Gəlin bu inputa parent funksiyasını bağlayaq,
o, inputun fokusu itirdikdə çağırılacaq:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
// Fokus itirildikdə çağırılacaq:
function parent() {
// burada hansısa kod olacaq
function child() {
// burada hansısa kod olacaq
}
child(); // daxili funksiyanı çağırırıq
}
Gəlin this-in məzmununu iki yerdə konsola çıxaraq:
parent funksiyasının içində və child funksiyasının içində:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this); // bizim inputa istinad çap edəcək
function child() {
console.log(this); // undefined çap edəcək
}
child();
}
Bu kodu işə salın, inputun fokusunu itirin
və konsola baxın - görəcəksiniz ki,
ilk console.log konsolda bizim inputa istinad çap edəcək,
ikincisi isə sadəcə undefined çap edəcək.
this-in bizim üçün gözlənilməz şəkildə bizə lazım olanı deyil,
başqa bir şeyi göstərdiyi belə bir vəziyyətə kontekst itkisi deyilir.
Tutaq ki, indi həm birinci, həm də ikinci funksiyada
biz inputun value dəyərini çap edirik. Şərh ilə qeyd olunan
kod sətirlərində nəyin çap olunacağını müəyyən edin:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this.value); // nə çap edəcək?
function child() {
console.log(this.value); // nə çap edəcək?
}
child();
}