El temido "this" en JavaScript, de una vez por todas

Si alguna vez te has quedado mirando una función y te has preguntado por qué this no apunta al objeto que esperabas, no estás solo. El comportamiento de this en JavaScript es una de esas trampas que aparecen cuando pasamos de la teoría a la práctica. En este artículo vamos a desmitificarlo, paso a paso, y a ofrecerte una hoja de ruta para que nunca más te sorprenda.
¿Qué es this y por qué nos confunde?
En esencia, this es una referencia al contexto de ejecución de una función. A diferencia de otros lenguajes, donde this siempre apunta al objeto que contiene el método, en JavaScript su valor depende de cómo se llama a la función, no de dónde está declarada. Esa sutileza es la que genera la mayor parte de los errores.
Reglas de enlace de this
- Modo por defecto (non‑strict): si llamas a una función sin un objeto explícito,
thisserá el objeto global (windowen el navegador). - Modo estricto: con
'use strict',thisseráundefineden llamadas directas. - Objetos implícitos: cuando usas la sintaxis
objeto.metodo(),thisapunta aobjeto. - Constructor (
new): al crear una instancia connew,thises el nuevo objeto que se está construyendo. - Funciones flecha: las arrow functions no tienen su propio
this; capturan el valor del entorno léxico donde se definieron. - Explicit binding: los métodos
call,applyybindpermiten fijarthisde forma manual.
Ejemplo práctico paso a paso
Veamos un caso real que suele generar dudas: un objeto con un método que llama a otra función interna.
const usuario = {
nombre: 'Álvaro',
saludo() {
console.log(Hola, soy ${this.nombre});
// Llamada a una función externa
mostrarEdad();
}
};
function mostrarEdad() {
// ¿Qué vale this aquí?
console.log(this.edad);
}
usuario.saludo(); // ¿Qué se muestra?
En el ejemplo anterior, this dentro de saludo apunta a usuario, pero mostrarEdad se ejecuta como una función regular, por lo que this será undefined (modo estricto) o window (modo no estricto). Para que mostrarEdad conozca el contexto correcto, podemos:
- Pasar explícitamente el objeto:
mostrarEdad.call(this); - Convertir
mostrarEdaden una arrow function, que heredathisdesaludo.
function mostrarEdad() {
console.log(this.edad);
}
const usuario = {
nombre: 'Álvaro',
edad: 30,
saludo() {
console.log(Hola, soy ${this.nombre});
mostrarEdad.call(this); // ahora funciona
}
};
usuario.saludo(); // Hola, soy Álvaro // 30
Otra alternativa es definir mostrarEdad como una arrow function dentro del objeto:
const usuario = {
nombre: 'Álvaro',
edad: 30,
saludo() {
console.log(Hola, soy ${this.nombre});
const mostrarEdad = () => console.log(this.edad);
mostrarEdad(); // hereda this de saludo
}
};
usuario.saludo();
Buenas prácticas y trucos para domar this
- Prefiere funciones flecha en callbacks: cuando el callback necesita acceder al mismo
thisdel contenedor, una arrow function evita sorpresas. - Usa
binden eventos: al pasar un método como manejador de eventos, enlázalo conthisdel componente o clase:this.handleClick = this.handleClick.bind(this); - Evita mezclar estilos: no combines funciones tradicionales y flechas en la misma lógica a menos que sepas exactamente qué valor tendrá
this. - Considera clases ES6: dentro de métodos de clase,
thisse comporta como en objetos tradicionales, pero los métodos que declares como arrow (por ejemplo en el constructor) capturan el contexto de la instancia.
Conclusión
El “temido” this deja de ser un misterio cuando recordamos que su valor se determina en el momento de la llamada, no en la declaración. Aplicar las reglas que hemos repasado, combinar funciones tradicionales y flechas de forma consciente, y aprovechar call/apply/bind cuando necesitemos forzar un contexto, te permitirá escribir código más predecible y libre de bugs relacionados con el alcance.
La próxima vez que veas un this inesperado, revisa primero cómo se está invocando la función y, si es necesario, reescribe el fragmento con una arrow function o con bind. Con práctica, ese “temido” se convertirá en tu aliado más fiable.