Kontekstin menetys JavaScriptissä
Oletetaan, että meillä on funktio funktion sisällä. Kutsutaan
ulompaa funktiota nimellä parent ja
sisemmästä - child:
function parent() {
function child() {
}
}
Aiemmista oppitunneista tiedät, että jos asetat minkä tahansa muuttujan ulompaan funktioon - se on saatavilla sisemmässä:
function parent() {
let str = 'abcde';
function child() {
console.log(str); // tulostaa 'abcde'
}
child(); // kutsutaan sisempää funktiota
}
parent(); // kutsutaan ulompaa funktiota
On kuitenkin vivahde: sisemmällä funktiolla on
pääsy kaikkiin ulomman funktion muuttujiin, mutta sillä
ei ole pääsyä this:iin. Eli: jos
ulompi funktio on sidottu johonkin DOM
elementtiin, niin this siinä viittaa
kyseiseen elementtiin, mutta this sisemmän
funktion - ei viittaa!
Mihin sitten this sisemmässä
funktiossa viittaa? Vastaus: se on yhtä suuri kuin
undefined (tiukassa tilassa), koska
funktio ei ole sidottu mihinkään.
Kokeillaan käytännössä. Oletetaan, että meillä on syöttökenttä:
<input id="elem" value="text">
Liitetään tähän syöttökenttään funktio parent,
jota kutsutaan, kun syöttökenttä menettää fokuksensa:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
// Kutsutaan fokuksen menetyksen yhteydessä:
function parent() {
// tässä on jotain koodia
function child() {
// tässä on jotain koodia
}
child(); // kutsutaan lapsifunktiota
}
Tuodaan this:n sisältö
konsoliin kahdessa kohdassa: funktion parent
sisällä ja funktion child sisällä:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this); // tulostaa viittauksen syöttökenttäämme
function child() {
console.log(this); // tulostaa undefined
}
child();
}
Suorita tämä koodi, hävitä syöttökentän fokus
ja katso konsolia - näet, että
ensimmäinen console.log tulostaa konsoliin
viittauksen syöttökenttäämme, ja toinen - pelkän undefined:n.
Tällaista tilannetta, jossa this odottamattomalla
tavalla viittaa ei siihen, mitä
tarvitsemme, kutsutaan kontekstin menetykseksi.
Oletetaan nyt, että sekä yhdessä että toisessa funktiossa
me tulostamme syöttökentän value:n. Määritä,
mitä tulostuu koodiriveille, jotka on merkitty
kommenteilla:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this.value); // mitä tulostaa?
function child() {
console.log(this.value); // mitä tulostaa?
}
child();
}