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

Si llevas tiempo programando en JavaScript, seguramente te ha surgido la duda (o el terror) de qué apunta this en cada contexto. No estás solo: el comportamiento de this es una de las preguntas más frecuentes entre principiantes y hasta entre desarrolladores con experiencia.
¿Qué es this?
En esencia, this es una referencia al objeto que está ejecutando la función actual. A diferencia de otros lenguajes, JavaScript no enlaza this en el momento de la definición, sino en el momento de la llamada.
Reglas básicas según el modo de llamada
- Llamada directa:
función()→thisesundefineden strict mode y el objeto global (windowen el navegador) en modo no estricto. - Método de objeto:
objeto.metodo()→thisesobjeto. - Constructor con
new:new Clase()→thises la nueva instancia creada. - Funciones flecha: heredan
thisdel entorno léxico donde se definieron, sin crear su propiothis.
Ejemplo práctico: método vs función
Veamos dos fragmentos que a simple vista parecen iguales, pero cuyo this varía.
const persona = {
nombre: 'Ana',
saludar: function() {
console.log('Hola, soy ' + this.nombre);
}
};
persona.saludar(); // Hola, soy Ana
const saludar = persona.saludar;
saludar(); // En modo estricto: TypeError (this is undefined)
En la primera llamada, saludar se invoca como método de persona, por lo que this apunta al propio objeto. En la segunda, la función se extrae y se ejecuta sin contexto, por lo que this pierde referencia.
El truco de bind, call y apply
Si necesitas forzar el valor de this, JavaScript te ofrece tres métodos:
func.bind(obj)devuelve una nueva función conthispermanentemente enlazado aobj.func.call(obj, arg1, arg2)invoca la función inmediatamente conthisigual aobjy los argumentos especificados.func.apply(obj, [arg1, arg2])funciona comocallpero recibe los argumentos como un array.
Ejemplo:
function presentar(saludo) {
console.log(saludo + ', soy ' + this.nombre);
}
const usuario = { nombre: 'Luis' };
const presentarUsuario = presentar.bind(usuario);
presentarUsuario('¡Hey'); // ¡Hey, soy Luis
presentar.call(usuario, 'Hola'); // Hola, soy Luis
presentar.apply(usuario, ['Buenas']); // Buenas, soy Luis
Funciones flecha: el aliado de los callbacks
Los callbacks dentro de métodos de clase son una fuente habitual de confusión. Las funciones flecha resuelven el problema porque no crean su propio this, sino que lo capturan del entorno donde se definieron.
class Contador {
constructor() {
this.cuenta = 0;
}
iniciar() {
setInterval(() => {
this.cuenta++;
console.log(this.cuenta);
}, 1000);
}
}
const c = new Contador();
c.iniciar(); // incrementa cada segundo sin perder referencia a "this"
Si hubiéramos usado una función tradicional dentro de setInterval, this se referiría al objeto global y el contador fallaría.
Consejos para evitar sorpresas
- Usa funciones flecha para callbacks que necesiten acceder a propiedades de la clase u objeto contenedor.
- Cuando declares métodos dentro de objetos literales, mantén la sintaxis
metodo() { … }(ES6) para que elthissea claro. - En entornos estrictos (
'use strict')thisnunca será el objeto global por accidente. - Revisa siempre el contexto antes de pasar una función como argumento; si es necesario, enlázala con
bind.
Resumen rápido
El comportamiento de this depende del cómo se llama a la función:
- Método de objeto →
this = objeto - Constructor con
new→this = instancia - Función normal →
this = undefined(strict) owindow(non‑strict) - Función flecha →
thisheredado del entorno léxico
Con estas reglas claras y los trucos de bind/call/apply, podrás domar al temido this y escribir código más predecible y mantenible.