Perdita del Contesto in JavaScript
Supponiamo di avere una funzione all'interno di un'altra funzione. Chiamiamo
la funzione esterna parent, e
quella interna - child:
function parent() {
function child() {
}
}
Dalle lezioni precedenti sai che se si definisce una variabile nella funzione esterna - essa sarà accessibile in quella interna:
function parent() {
let str = 'abcde';
function child() {
console.log(str); // stamperà 'abcde'
}
child(); // chiamiamo la funzione interna
}
parent(); // chiamiamo la funzione esterna
C'è, tuttavia, una sfumatura: la funzione interna ha
accesso a tutte le variabili di quella esterna, ma non
ha accesso a this. Cioè: se
la funzione esterna è associata a un qualche elemento DOM,
allora this in essa si riferirà
a quell'elemento, ma this della funzione
interna - non lo farà!
A cosa si riferirà allora this
della funzione interna? Risposta: sarà uguale a
undefined (in modalità strict),
poiché la funzione non è associata a nulla.
Verifichiamolo nella pratica. Supponiamo di avere un input:
<input id="elem" value="text">
Associamo a questo input la funzione parent,
che verrà chiamata quando l'input perde il focus:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
// Verrà chiamata alla perdita del focus:
function parent() {
// qui ci sarà del codice
function child() {
// qui ci sarà del codice
}
child(); // chiamiamo la funzione figlia
}
Stampiamo il contenuto di this nella
console in due punti: all'interno della funzione parent
e all'interno della funzione child:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this); // stamperà il riferimento al nostro input
function child() {
console.log(this); // stamperà undefined
}
child();
}
Esegui questo codice, fai perdere il focus all'input
e guarda nella console - vedrai che
il primo console.log stamperà in console
il riferimento al nostro input, mentre il secondo - semplicemente undefined.
Questa situazione, in cui this in modo inaspettato
non si riferisce a ciò di cui abbiamo
bisogno, è chiamata perdita del contesto.
Supponiamo ora che in entrambe le funzioni
stampiamo il value dell'input. Determina
cosa verrà stampato nelle righe di codice, indicate
dai commenti:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this.value); // cosa stamperà?
function child() {
console.log(this.value); // cosa stamperà?
}
child();
}