Tap av kontekst i JavaScript
La oss si at vi har en funksjon inni en funksjon. La oss
kalle den ytre funksjonen parent, og
den indre - child:
function parent() {
function child() {
}
}
Fra tidligere leksjoner vet du at hvis du setter en variabel i den ytre funksjonen - vil den være tilgjengelig i den indre:
function parent() {
let str = 'abcde';
function child() {
console.log(str); // vil skrive ut 'abcde'
}
child(); // kaller den indre funksjonen
}
parent(); // kaller den ytre funksjonen
Det er imidlertid en nyanse: den indre funksjonen har
tilgang til alle variablene til den ytre, men har
ikke tilgang til this. Det vil si: hvis
den ytre funksjonen er bundet til et DOM-element,
vil this i den peke på det elementet,
men this i den indre funksjonen - vil ikke!
Hva vil da this i den indre funksjonen
peke på? Svar: den vil være lik
undefined (i streng modus), fordi
funksjonen ikke er bundet til noe.
La oss teste dette i praksis. La oss si at vi har et input-felt:
<input id="elem" value="text">
La oss binde funksjonen parent til dette input-feltet,
som skal kalles når input-feltet mister fokus:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
// Kalles ved tap av fokus:
function parent() {
// det vil være noe kode her
function child() {
// det vil være noe kode her
}
child(); // kaller barnefunksjonen
}
La oss skrive ut innholdet i this til
konsollen på to steder: inne i funksjonen parent
og inne i funksjonen child:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this); // vil skrive ut en referanse til input-feltet vårt
function child() {
console.log(this); // vil skrive ut undefined
}
child();
}
Kjør denne koden, la input-feltet miste fokus
og se i konsollen - du vil se at
den første console.log vil skrive ut
en referanse til input-feltet vårt, og den andre - bare undefined.
En slik situasjon, hvor this på en uventet
måte ikke peker på det vi trenger, kalles tap av kontekst.
La oss nå i både den ene og den andre funksjonen
skrive ut value til input-feltet. Bestem
hva som vil skrives ut i kodelinjene merket med
kommentarer:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this.value); // hva vil skrives ut?
function child() {
console.log(this.value); // hva vil skrives ut?
}
child();
}