Konteksto praradimas JavaScript
Tarkime, kad turime funkciją funkcijoje. Išorinę
funkciją pavadinkime parent, o
vidinę - child:
function parent() {
function child() {
}
}
Iš ankstesnių pamokų žinote, kad jei kintamajam priskirsime reikšmę išorinėje funkcijoje - jis bus prieinamas vidinėje:
function parent() {
let str = 'abcde';
function child() {
console.log(str); // išves 'abcde'
}
child(); // iškviečiame vidinę funkciją
}
parent(); // iškviečiame išorinę funkciją
Tačiau yra niuansas: vidinė funkcija turi
prieigą prie visų išorinės funkcijos kintamųjų, bet
neturi prieigos prie this. Tai reiškia: jei
išorinė funkcija yra susieta su kokiu nors DOM
elementu, tai this joje rodys
į tą elementą, tačiau this vidinės
funkcijos - nerodys!
Į ką tuomet rodys this
vidinėje funkcijoje? Atsakymas: jis bus lygus
undefined ( griežtuoju režimu), nes
funkcija nieko nėra pririšta.
Patikrinkime praktiškai. Tarkime, kad turime input elementą:
<input id="elem" value="text">
Pririškime prie šio input elemento funkciją parent,
kuri bus iškviečiama praradus fokusą input elementui:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
// Bus iškviesta praradus fokusą:
function parent() {
// čia bus kažkoks kodas
function child() {
// čia bus kažkoks kodas
}
child(); // iškviečiame vidinę funkciją
}
Išveskime this turinį į
konsolę dviejose vietose: funkcijos parent
viduje ir funkcijos child viduje:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this); // išves mūsų input elemento nuorodą
function child() {
console.log(this); // išves undefined
}
child();
}
Paleiskite šį kodą, input elementui praraskite fokusą
ir pažiūrėkite į konsolę - pamatysite, kad
pirmasis console.log išves į konsolę
mūsų input elemento nuorodą, o antrasis - tiesiog undefined.
Tokia situacija, kai this netikėtai
mums rodo ne ten, kur mums
reikia, vadinama konteksto praradimu.
Tarkime, kad dabar vienoje ir antroje funkcijoje
mes išvesime input elemento value. Nustatykite,
ką išves kodo eilutės, pažymėtos
komentarais:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this.value); // ką išves?
function child() {
console.log(this.value); // ką išves?
}
child();
}