Izguba konteksta v JavaScript
Recimo, da imamo funkcijo znotraj funkcije. Zunanjo
funkcijo poimenujmo parent,
notranjo pa child:
function parent() {
function child() {
}
}
Iz prejšnjih lekcij veste, da če nastavite katero koli spremenljivko v zunanji funkciji - bo dostopna v notranji:
function parent() {
let str = 'abcde';
function child() {
console.log(str); // izpiše 'abcde'
}
child(); // pokličemo notranjo funkcijo
}
parent(); // pokličemo zunanjo funkcijo
Vendar obstaja odtenek: notranja funkcija ima
dostop do vseh spremenljivk zunanje, vendar
nima dostopa do this. To pomeni: če
je zunanja funkcija vezana na nek DOM
element, bo this v njej kazal
na ta element, vendar this notranje
funkcije - ne bo!
Na kaj bo potem kazal this
notranje funkcije? Odgovor: enak bo
undefined (v strogem načinu), ker
funkcija ni na nič vezana.
Preverimo v praksi. Recimo, da imamo dan vnosno polje:
<input id="elem" value="text">
Povežimo to vnosno polje s funkcijo parent,
ki se bo klicala ob izgubi fokusa vnosnega polja:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
// Pokliče se ob izgubi fokusa:
function parent() {
// tukaj bo nekaj kode
function child() {
// tukaj bo nekaj kode
}
child(); // kličemo podrejeno funkcijo
}
Izpišimo vsebino this v
konzolo na dveh mestih: znotraj funkcije parent
in znotraj funkcije child:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this); // izpiše referenco na naše vnosno polje
function child() {
console.log(this); // izpiše undefined
}
child();
}
Zaženite to kodo, povzročite izgubo fokusa vnosnega polja
in poglejte v konzolo - videli boste, da
bo prvi console.log izpisal v konzolo
referenco na naše vnosno polje, drugi pa - preprosto undefined.
Takšna situacija, ko this na nepričakovan
način ne kaže na tisto, kar
potrebujemo, se imenuje izguba konteksta.
Recimo, da zdaj v prvi in v drugi funkciji
izpisujemo value vnosnega polja. Določite,
kaj se bo izpisalo v vrsticah kode, označenih
s komentarji:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this.value); // kaj bo izpisalo?
function child() {
console.log(this.value); // kaj bo izpisalo?
}
child();
}