Konteksta zaudēšana JavaScript
Pieņemsim, ka mums ir funkcija funkcijā. Ārējo funkciju
nosauksim par parent, bet
iekšējo - par child:
function parent() {
function child() {
}
}
No iepriekšējām nodarbībām jūs zināt, ka, ja kādu mainīgo definē ārējā funkcijā - tas būs pieejams iekšējā:
function parent() {
let str = 'abcde';
function child() {
console.log(str); // izvadīs 'abcde'
}
child(); // izsaucam iekšējo funkciju
}
parent(); // izsaucam ārējo funkciju
Tomēr ir nianse: iekšējai funkcijai ir
pieeja visiem ārējās funkcijas mainīgajiem, bet tai nav
pieejas this. Tas nozīmē: ja
ārējā funkcija ir piesaistīta kādam DOM
elementam, tad this tajā norādīs
uz šo elementu, bet this iekšējās
funkcijas - nenorādīs!
Uz ko tad norādīs this
iekšējā funkcijā? Atbilde: tas būs vienāds ar
undefined (stingrajā režīmā), jo
funkcija nav pie nekam piesaistīta.
Pārbaudīsim praksē. Pieņemsim, ka mums ir dots input lauks:
<input id="elem" value="text">
Piesēdīsim šim input laukam funkciju parent,
kas tiks izsaukta, kad input lauks zaudē fokusu:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
// Izsaukšanās notiks, zaudējot fokusu:
function parent() {
// šeit būs kāds kods
function child() {
// šeit būs kāds kods
}
child(); // izsaucam apakšfunkciju
}
Izvadīsim this saturu
konsole divās vietās: funkcijas parent
iekšienē un funkcijas child iekšienē:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this); // izvadīs saiti uz mūsu input lauku
function child() {
console.log(this); // izvadīs undefined
}
child();
}
Palaidiet šo kodu, lieciet input laukam zaudēt fokusu
un apskatiet konsoli - jūs redzēsiet, ka
pirmais console.log izvadīs konsolē
saiti uz mūsu input lauku, bet otrais - vienkārši undefined.
Tāda situācija, kad this negaidīti
priekš mums norāda ne uz to, kas mums
vajadzīgs, tiek saukta par konteksta zaudēšanu.
Pieņemsim, ka tagad vienā un otrajā funkcijā
mēs izvadīsim input lauka value. Nosakiet,
kas tiks izvadīts koda rindiņās, atzīmētās
ar komentāriem:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this.value); // ko izvadīs?
function child() {
console.log(this.value); // ko izvadīs?
}
child();
}