Pérdida de contexto en JavaScript
Supongamos que tenemos una función dentro de otra. Llamemos
a la función externa parent y
a la interna - child:
function parent() {
function child() {
}
}
Por lecciones anteriores sabes que si se establece alguna variable en la función externa, estará disponible en la interna:
function parent() {
let str = 'abcde';
function child() {
console.log(str); // mostrará 'abcde'
}
child(); // llamamos a la función interna
}
parent(); // llamamos a la función externa
Sin embargo, hay un matiz: la función interna tiene
acceso a todas las variables de la externa, pero no
tiene acceso a this. Es decir: si
la función externa está vinculada a algún elemento DOM,
entonces this en ella apuntará
a ese elemento, ¡pero this de la función
interna - no lo hará!
¿A qué apuntará entonces this
de la función interna? Respuesta: será igual
a undefined (en modo estricto), ya
que la función no está vinculada a nada.
Comprobemos esto en la práctica. Supongamos que tenemos un input:
<input id="elem" value="text">
Vinculamos a este input la función parent,
que se llamará cuando el input pierda el foco:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
// Se llamará al perder el foco:
function parent() {
// aquí habrá algún código
function child() {
// aquí habrá algún código
}
child(); // llamamos a la función hija
}
Mostremos el contenido de this en
la consola en dos lugares: dentro de la función parent
y dentro de la función child:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this); // mostrará la referencia a nuestro input
function child() {
console.log(this); // mostrará undefined
}
child();
}
Ejecuta este código, haz que el input pierda el foco
y mira la consola: verás que
el primer console.log mostrará en la consola
la referencia a nuestro input, y el segundo - simplemente undefined.
Esta situación, cuando this de manera
inesperada para nosotros apunta no a lo que
necesitamos, se llama pérdida de contexto.
Supongamos ahora que en ambas funciones
mostramos el value del input. Determina,
què se mostrará en las líneas de código marcadas con
comentarios:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this.value); // ¿qué mostrará?
function child() {
console.log(this.value); // ¿qué mostrará?
}
child();
}