¿Qué es `this` en JavaScript y cómo se determina su valor?
Ver respuesta — intenta responderla en voz alta primero
this es una referencia al contexto de ejecución. Su valor no depende de dónde se define la función, sino de cómo se la llama. Las arrow functions son la excepción: heredan this del ámbito donde se crean.
El valor de this cambia según cómo llames a la función:
- Método de un objeto (
obj.metodo()):thises el objeto (obj). - Función independiente (
funcion()):thisesundefineden modo estricto, o el objeto global en otro caso. - Con
new:thises el nuevo objeto que se está creando. - Con
call,applyobind:thises lo que tú especifiques. - Arrow function: no tiene
thispropio; usa el del ámbito donde fue definida.
La clave: fíjate en cómo se invoca la función, no en dónde está escrita.
// 1. Método de un objeto
const usuario = {
nombre: "Mike",
saludar() {
console.log(this.nombre);
},
};
usuario.saludar(); // "Mike" (this es usuario)
// 2. La misma función, pero "independiente", pierde this
const independiente = usuario.saludar;
// independiente(); // undefined (this ya no es usuario)
// 3. bind fija this
const enlazada = usuario.saludar.bind(usuario);
enlazada(); // "Mike"
// 4. Una arrow hereda this del ámbito
const equipo = {
nombre: "DevByMike",
miembros: ["Ana", "Luis"],
listar() {
this.miembros.forEach((m) => {
// la arrow usa el this de listar, que es equipo
console.log(`${m} pertenece a ${this.nombre}`);
});
},
};
equipo.listar();
// "Ana pertenece a DevByMike"
// "Luis pertenece a DevByMike"
Suponer que this depende de dónde se escribió la función. En realidad depende de cómo se la llama. Por eso, cuando guardas un método en una variable y lo llamas de forma independiente (const f = obj.metodo; f();), this deja de ser el objeto.
"
thises una referencia al contexto de ejecución, y lo importante es que su valor depende de cómo se llama a la función, no de dónde se define. Si llamo a un método conobj.metodo(),thisesobj. Si llamo a la función de forma independiente,thises undefined en modo estricto. Connewes el nuevo objeto, y concall,applyobinddecido qué es. Las arrow functions son la excepción: heredanthisdel ámbito donde las escribí."
¿Qué imprime esto?
const contador = {
total: 0,
incrementar() {
this.total++;
},
};
const inc = contador.incrementar;
inc();
console.log(contador.total);
Ver respuesta
Imprime 0 (y en modo estricto probablemente lance un error). Al guardar el método en inc y llamarlo de forma independiente, this ya no es contador, así que no incrementa contador.total.