7. ¿Qué es la palabra clave "this" en JS? - KatherineAGM/Checkpoint-7 GitHub Wiki
La palabra clave this
es una de las características más poderosas y, a la vez, una de las más confusas para quienes están empezando. Su valor no es fijo; en cambio, el valor de this
depende del contexto en el que se llama a la función.
No hace referencia a la función en sí misma, ni tampoco al ámbito léxico de la función. Más bien, hace referencia al objeto al que pertenece la función o al objeto que invoca la función.
Entendiendo el Contexto de this
El valor de this
cambia según cómo se invoca la función. Aquí están los casos más comunes:
1. Contexto Global (fuera de cualquier función o dentro de funciones regulares no en modo estricto):
-
En el navegador,
this
hace referencia al objetowindow
(el objeto global). -
En Node.js,
this
hace referencia al objetoglobal
o amodule.exports
dependiendo del contexto del módulo. -
En modo estricto (
'use strict';
), en el contexto global,this
esundefined
.
console.log(this === window); // En el navegador: true
console.log(this); // En Node.js: {} o similar (dependiendo del contexto)
function funcionGlobal() {
console.log(this === window); // En el navegador: true (si no hay modo estricto)
}
funcionGlobal();
2. Como Método de un Objeto (Method Invocation):
- Cuando una función se invoca como un método de un objeto,
this
hace referencia a ese objeto que posee el método.
const persona = {
nombre: "Alicia",
saludar: function() {
console.log(`Hola, soy ${this.nombre}`); // 'this' se refiere al objeto 'persona'
}
};
persona.saludar(); // Salida: "Hola, soy Alicia"
const coche = {
marca: "Toyota",
mostrarMarca: function() {
console.log(this.marca); // 'this' se refiere al objeto 'coche'
}
};
coche.mostrarMarca(); // Salida: "Toyota"
3. Como Función Regular (Function Invocation - en modo no estricto):
- Cuando una función no es un método de un objeto y se llama de forma "normal",
this
hace referencia al objeto global (window
en navegadores,undefined
oglobal
en Node.js, dependiendo del contexto). ¡Esta es una fuente común de confusión!
const otraPersona = {
nombre: "Carlos",
saludar: function() {
// En este contexto, 'this' se refiere a 'otraPersona'
const mostrarNombre = function() {
// Dentro de esta función anidada, 'this' por defecto apunta al objeto global (window)
// a menos que estemos en modo estricto o sea una arrow function.
console.log(this.nombre); // Esto podría ser 'undefined' o error si no hay 'nombre' en el global
};
mostrarNombre();
}
};
otraPersona.saludar(); // Salida: undefined (o error) si 'window.nombre' no existe
'use strict';
):
4. En Modo Estricto (- Si una función se llama en modo estricto (ya sea porque todo el archivo está en modo estricto o solo la función), y no se llama como un método de un objeto,
this
seráundefined
. Esto ayuda a prevenir errores comunes y hace el comportamiento dethis
más predecible.
'use strict';
function funcionEnModoEstricto() {
console.log(this); // Salida: undefined
}
funcionEnModoEstricto();
const obj = {
metodoEstricto: function() {
console.log(this); // Salida: { metodoEstricto: [Function: metodoEstricto] } (sigue siendo el objeto)
}
};
obj.metodoEstricto();
new
Keyword):
5. Con Constructores (- Cuando una función se usa como constructor (llamada con la palabra clave
new
),this
hace referencia a la nueva instancia del objeto que se está creando.
function Coche(marca) {
this.marca = marca; // 'this' es la nueva instancia de Coche
this.obtenerMarca = function() {
console.log(this.marca);
};
}
const miCoche = new Coche("Ford");
miCoche.obtenerMarca(); // Salida: "Ford"
call()
, apply()
, y bind()
:
6. Con Métodos -
Estos métodos (
Function.prototype.call()
,Function.prototype.apply()
,Function.prototype.bind()
) permiten establecer explícitamente el valor dethis
al llamar a una función. -
call()
yapply()
invocan la función inmediatamente, pasando el primer argumento como el valor dethis
. -
bind()
devuelve una nueva función conthis
"vinculado" permanentemente al valor especificado.
const persona1 = { nombre: "Ana" };
const persona2 = { nombre: "Luis" };
function presentar(saludo) {
console.log(`${saludo}, soy ${this.nombre}`);
}
presentar.call(persona1, "Hola"); // Salida: "Hola, soy Ana"
presentar.apply(persona2, ["Qué tal"]); // Salida: "Qué tal, soy Luis"
const presentarAna = presentar.bind(persona1, "Saludos");
presentarAna(); // Salida: "Saludos, soy Ana"
7. Con Funciones Flecha (Arrow Functions):
- Las funciones flecha (
=>
) tienen un comportamiento muy diferente parathis
. No tienen su propiothis
"vinculado"; en cambio, capturan el valor dethis
del ámbito léxico (del ámbito en el que se definen). Esto las hace muy útiles para evitar el problema dethis
en callbacks anidados.
const usuario = {
nombre: "Elena",
saludarConRetraso: function() {
// En esta función tradicional, 'this' es 'usuario'
setTimeout(() => {
// La función flecha captura el 'this' de su ámbito externo (la función saludarConRetraso)
console.log(`Hola, ${this.nombre}`);
}, 1000);
}
};
usuario.saludarConRetraso(); // Salida (después de 1 segundo): "Hola, Elena"
// Si hubiéramos usado una función tradicional anidada aquí:
const usuario2 = {
nombre: "Pedro",
saludarMal: function() {
setTimeout(function() {
console.log(`Hola, ${this.nombre}`); // 'this' aquí sería 'window' o 'undefined' en modo estricto
}, 1000);
}
};
usuario2.saludarMal(); // Salida (después de 1 segundo): "Hola, undefined" o "Hola, [nombre global]"
La palabra clave this
en JavaScript es altamente dinámica y su valor es determinado por el contexto de ejecución de la función. Entender cómo se comporta this
en cada uno de estos escenarios es crucial para escribir código JavaScript efectivo y libre de errores. Las funciones flecha han simplificado significativamente el manejo de this
en muchos escenarios, especialmente en callbacks.