A kontextus elvesztése JavaScriptben
Tegyük fel, hogy van egy függvényünk egy függvényben. Nevezzük
a külső függvényt parent-nak (szülő), a
belsőt pedig child-nak (gyermek):
function parent() {
function child() {
}
}
A korábbi leckékből tudod, hogy ha egy változót a külső függvényben hozol létre, az elérhető lesz a belső függvényben is:
function parent() {
let str = 'abcde';
function child() {
console.log(str); // kiírja 'abcde'-t
}
child(); // meghívjuk a belső függvényt
}
parent(); // meghívjuk a külső függvényt
Van azonban egy apró részlet: a belső függvény hozzáfér a külső függvény
összes változójához, de ⁅nem⁆ fér hozzá a this-hez. Azaz: ha
a külső függvény egy DOM elemhez van kötve, akkor a this benne
arra az elemre fog mutatni, de a belső függvény this értéke ⁅nem⁆!
De akkor mire fog mutatni a belső függvény this értéke?
A válasz: undefined lesz (strict módban),
mivel a függvény nincs semmihez kötve.
Vizsgáljuk meg ezt a gyakorlatban. Tegyük fel, hogy van egy input mezőnk:
<input id="elem" value="text">
Kössük ehhez az input mezőhöz a parent függvényt,
amely akkor hívódik meg, amikor az input elveszti a fókuszt:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
// Fókuszvesztéskor hívódik meg:
function parent() {
// itt lesz valamilyen kód
function child() {
// itt lesz valamilyen kód
}
child(); // meghívjuk a gyermek függvényt
}
Írjuk ki a this tartalmát a konzolra két helyen:
a parent függvényen belül és a child
függvényen belül:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this); // kiírja az input mező referenciáját
function child() {
console.log(this); // kiírja undefined-ot
}
child();
}
Futtasd ezt a kódot, vond el az input fókuszt,
és nézd meg a konzolt - látni fogod, hogy
az első console.log kiírja a konzolra
az input mező referenciáját, a második pedig egyszerűen undefined-ot.
Ezt a helyzetet, amikor a this váratlanul
nem arra mutat, amire szeretnénk, kontextus elvesztésének nevezzük.
Tegyük fel, hogy most mindkét függvényben
kiírjuk az input value (érték) tulajdonságát. Határozd meg,
hogy mit írnak ki a megjegyzésekkel jelölt
kódsorok:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this.value); // mit ír ki?
function child() {
console.log(this.value); // mit ír ki?
}
child();
}