Pierderea contextului în JavaScript
Să presupunem că avem o funcție în interiorul altei funcții. Să
numim funcția exterioară parent, iar
funcția interioară - child:
function parent() {
function child() {
}
}
Din lecțiile anterioare știți deja că dacă definiți o variabilă în funcția exterioară - ea va fi accesibilă în funcția interioară:
function parent() {
let str = 'abcde';
function child() {
console.log(str); // va afișa 'abcde'
}
child(); // apelăm funcția interioară
}
parent(); // apelăm funcția exterioară
Există, totuși, o nuanță: funcția interioară are
acces la toate variabilele funcției exterioare, dar nu
are acces la this. Adică: dacă
funcția exterioară este legată de un element DOM,
atunci this în ea va indica
către acel element, dar this din funcția
interioară - nu va indica!
Atunci la ce va indica this
în funcția interioară? Răspunsul: va fi egal cu
undefined (în modul strict), deoarece
funcția nu este legată de nimic.
Să verificăm în practică. Să presupunem că avem un input:
<input id="elem" value="text">
Să legăm de acest input funcția parent,
care va fi apelată la pierderea focusului de către input:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
// Se va apela la pierderea focusului:
function parent() {
// aici va fi un cod oarecare
function child() {
// aici va fi un cod oarecare
}
child(); // apelăm funcția copil
}
Să afișăm conținutul lui this în
consolă în două locuri: în interiorul funcției parent
și în interiorul funcției child:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this); // va afișa referința la input-ul nostru
function child() {
console.log(this); // va afișa undefined
}
child();
}
Rulați acest cod, pierdeți focusul input-ului
și uitați-vă în consolă - veți vedea că
primul console.log va afișa în consolă
referința la input-ul nostru, iar al doilea - simplu undefined.
O astfel de situație, când this într-un mod
neașteptat pentru noi nu indică către ceea ce
avem nevoie, se numește pierderea contextului.
Să presupunem acum că în prima și în a doua funcție
vom afișa value al input-ului. Determinați,
ce se va afișa în liniile de cod, marcate cu
comentarii:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this.value); // ce va afișa?
function child() {
console.log(this.value); // ce va afișa?
}
child();
}