EL SCOPE en JAVASCRIPT | JS en ESPAÑOL--this
Contexto de Ejecución, this y Funciones Flecha en JavaScript
¡Excelente pregunta! Justo mencionamos que scope y contexto no son lo mismo. Ahora vamos a aclarar qué es el contexto de ejecución y esa palabra mágica llamada this.
📦 Contexto de Ejecución vs Scope (el resumen que necesitas)
| Concepto | ¿Qué es? | ¿Qué determina? |
|---|---|---|
| Scope | El lugar donde vive una variable | QUÉ variables puedo usar |
| Contexto | El objeto que está ejecutando la función | QUIÉN es el dueño de la función |
Analogía rápida:
El scope es como tu casa (dónde vives y qué cosas tienes)
El contexto/
thises como tú (quién está haciendo la acción ahora)
🏠 Analogía principal: La fiesta en casa
Imagina que estás en una fiesta en tu casa:
const anfitrion = {
nombre: 'Carlos',
casa: 'Calle Falsa 123',
saludar() {
console.log(`Hola, soy ${this.nombre} y esta es mi fiesta`);
}
};
anfitrion.saludar(); // "Hola, soy Carlos y esta es mi fiesta"this= el anfitrión (Carlos)El contexto = quién está hablando ahora (Carlos)
Si llega un invitado y trata de saludar usando this:
const invitado = {
nombre: 'Ana',
saludar() {
console.log(`Hola, soy ${this.nombre} y soy invitado`);
}
};
invitado.saludar(); // "Hola, soy Ana y soy invitado"Cada función tiene SU propio this según quién la ejecuta.
🔍 ¿Qué es this exactamente?
this es una palabra especial que apunta al objeto que está ejecutando la función en ese momento.
Caso 1: this en un método de objeto
const persona = {
nombre: 'Luis',
decirNombre() {
console.log(this.nombre);
}
};
persona.decirNombre(); // "Luis" → this = personaCaso 2: this en una función suelta
function saludar() {
console.log(this);
}
saludar(); // window (en navegador) o global (en Node)En una función normal y suelta, this apunta al objeto global (window).
Caso 3: this dentro de otra función
¡Aquí viene el PROBLEMA CLÁSICO!
const coche = {
marca: 'Toyota',
mostrarMarca: function() {
console.log(this.marca); // ✅ "Toyota"
function interna() {
console.log(this.marca); // ❌ undefined
}
interna();
}
};
coche.mostrarMarca();¿Por qué falla? Porque la función interna es una función suelta, y su this es el objeto global, no el coche.
🏹 Funciones Flecha: La solución mágica
Las funciones flecha NO tienen su propio this. Ellas toman el this del lugar donde fueron escritas (scope padre).
Comparativa visual:
const persona = {
nombre: 'María',
// Función normal
saludarNormal: function() {
setTimeout(function() {
console.log('Normal: Hola ' + this.nombre); // ❌ undefined
}, 100);
},
// Función flecha
saludarFlecha: function() {
setTimeout(() => {
console.log('Flecha: Hola ' + this.nombre); // ✅ "Hola María"
}, 100);
}
};
persona.saludarNormal(); // Normal: Hola undefined
persona.saludarFlecha(); // Flecha: Hola MaríaExplicación:
Función normal dentro de
setTimeout→ suthises el objeto globalFunción flecha → NO tiene
thispropio, usa elthisdesaludarFlecha(que espersona)
🧠 Analogía: El walkie-talkie
Imagina que tienes un walkie-talkie:
Función normal = Cada persona tiene SU PROPIO walkie-talkie. Si cambias de persona, cambia el dispositivo.
Función flecha = No tienes walkie-talkie propio. Usas el de la persona que te dio el dispositivo.
const jefe = {
nombre: 'Jefe',
orden: 'Trabajar',
darOrdenNormal: function() {
console.log(`Yo, ${this.nombre}, ordeno: ${this.orden}`);
function empleado() {
console.log(`El empleado dice: ${this.orden}`); // ❌ this.orden = undefined
}
empleado();
},
darOrdenFlecha: function() {
console.log(`Yo, ${this.nombre}, ordeno: ${this.orden}`);
const empleado = () => {
console.log(`El empleado dice: ${this.orden}`); // ✅ "Trabajar"
}
empleado();
}
};
jefe.darOrdenNormal(); // El empleado no escucha la orden
jefe.darOrdenFlecha(); // El empleado repite la orden del jefe📝 Ejemplos pequeños para entender todo
1. this cambia según CÓMO llamas a la función
function quienSoy() {
console.log(this.nombre);
}
const persona1 = { nombre: 'Ana', quienSoy };
const persona2 = { nombre: 'Carlos', quienSoy };
persona1.quienSoy(); // "Ana" → this = persona1
persona2.quienSoy(); // "Carlos" → this = persona2ejemplo 2:
// Igual que el ejemplo 1, pero con funciones flecha
function quienSoyNormal() {
console.log(this.nombre);
}
const quienSoyFlecha = () => {
console.log(this.nombre);
};
const persona1 = {
nombre: 'Ana',
quienSoyNormal,
quienSoyFlecha
};
const persona2 = {
nombre: 'Carlos',
quienSoyNormal,
quienSoyFlecha
};
// Funciones normales: this cambia según quién llama
persona1.quienSoyNormal(); // "Ana" → this = persona1
persona2.quienSoyNormal(); // "Carlos" → this = persona2
// Funciones flecha: this NO cambia (hereda del contexto donde se definió)
persona1.quienSoyFlecha(); // undefined (o error) → this = global/window
persona2.quienSoyFlecha(); // undefined (o error) → this = global/window
// Igual que el ejemplo 1, pero con funciones flecha function quienSoyNormal() { console.log(this.nombre); } const quienSoyFlecha = () => { console.log(this.nombre); }; const persona1 = { nombre: 'Ana', quienSoyNormal, quienSoyFlecha }; const persona2 = { nombre: 'Carlos', quienSoyNormal, quienSoyFlecha }; // Funciones normales: this cambia según quién llama persona1.quienSoyNormal(); // "Ana" → this = persona1 persona2.quienSoyNormal(); // "Carlos" → this = persona2 // Funciones flecha: this NO cambia (hereda del contexto donde se definió) persona1.quienSoyFlecha(); // undefined (o error) → this = global/window persona2.quienSoyFlecha(); // undefined (o error) → this = global/window
La diferencia clave mostrada de forma visual:
Función normal Función flecha Contexto Cambia según quién llama Hereda del lugar donde se creó persona1.funcion()this = persona1 ✅this = contexto global ❌persona2.funcion()this = persona2 ✅this = contexto global ❌
| Función normal | Función flecha | |
|---|---|---|
| Contexto | Cambia según quién llama | Hereda del lugar donde se creó |
persona1.funcion() | this = persona1 ✅ | this = contexto global ❌ |
persona2.funcion() | this = persona2 ✅ | this = contexto global ❌ |
2. Las funciones flecha NO cambian su this
const equipo = {
nombre: 'Real Madrid',
jugadores: ['Vinicius', 'Bellingham'],
mostrarJugadores: function() {
// Flecha: usa el this de mostrarJugadores (equipo)
this.jugadores.forEach((jugador) => {
console.log(`${this.nombre}: ${jugador}`); // ✅ funciona
});
// Normal: crearía su propio this (undefined)
// this.jugadores.forEach(function(jugador) {
// console.log(`${this.nombre}: ${jugador}`); // ❌ falla
// });
}
};
equipo.mostrarJugadores();
// "Real Madrid: Vinicius"
// "Real Madrid: Bellingham"3. En eventos del navegador
const boton = document.querySelector('button');
// Función normal: this = el botón
boton.addEventListener('click', function() {
console.log(this); // el elemento botón
this.style.backgroundColor = 'red'; // ✅ funciona
});
// Función flecha: this = window (o el contexto padre)
boton.addEventListener('click', () => {
console.log(this); // window
this.style.backgroundColor = 'red'; // ❌ no funciona
});🎯 Reglas de oro (memoriza esto)
| Situación | Valor de this |
|---|---|
Método de objeto (obj.metodo()) | El objeto (obj) |
Función suelta (function(){}) | Objeto global (window) |
Función flecha (() => {}) | El this del lugar donde fue escrita |
Constructor (new Persona()) | El nuevo objeto creado |
call / apply / bind | El objeto que le pases |
⚡ Resumen visual
// Contexto = QUIÉN ejecuta
// this = la palabra que representa a ese QUIÉN
const humano = {
nombre: 'Pedro',
// Función normal → tiene su propio this (el objeto)
normal: function() {
console.log(this.nombre); // "Pedro"
},
// Función flecha → NO tiene this, usa el de afuera
flecha: () => {
console.log(this.nombre); // undefined (this es window)
}
};
// PERO OJO: si la flecha está DENTRO de una función normal, agarra el this de esa función
const humano2 = {
nombre: 'Laura',
accion: function() {
const flechaInterna = () => {
console.log(this.nombre); // "Laura" ✅
};
flechaInterna();
}
};Resultados:
const humano = {
nombre: 'Pedro',
normal: function() {
console.log(this.nombre); // "Pedro"
},
flecha: () => {
console.log(this.nombre); // undefined (this es window)
}
};
humano.normal(); // ✅ "Pedro"
humano.flecha(); // ❌ undefined
// ======================================
const humano2 = {
nombre: 'Laura',
accion: function() {
const flechaInterna = () => {
console.log(this.nombre); // "Laura" ✅
};
flechaInterna();
}
};
humano2.accion(); // ✅ "Laura"
const humano = { nombre: 'Pedro', normal: function() { console.log(this.nombre); // "Pedro" }, flecha: () => { console.log(this.nombre); // undefined (this es window) } }; humano.normal(); // ✅ "Pedro" humano.flecha(); // ❌ undefined // ====================================== const humano2 = { nombre: 'Laura', accion: function() { const flechaInterna = () => { console.log(this.nombre); // "Laura" ✅ }; flechaInterna(); } }; humano2.accion(); // ✅ "Laura"
Explicación línea por línea:
Llamada Resultado ¿Por qué? humano.normal()"Pedro"Función NORMAL → this = humano (quien la ejecuta) humano.flecha()undefinedFunción FLECHA → this = window (contexto donde se definió) humano2.accion()"Laura"accion es normal → this = humano2
La flecha interna HEREDA ese this
| Llamada | Resultado | ¿Por qué? |
|---|---|---|
humano.normal() | "Pedro" | Función NORMAL → this = humano (quien la ejecuta) |
humano.flecha() | undefined | Función FLECHA → this = window (contexto donde se definió) |
humano2.accion() | "Laura" | accion es normal → this = humano2La flecha interna HEREDA ese this |
Regla visual:
Función NORMAL → this = quien está a la izquierda del .
Función FLECHA → this = quien estaba a la izquierda del . cuando se CREÓ
humano.normal() → normal ve a humano → "Pedro" ✅
humano.flecha() → flecha se creó en global → window.nombre → undefined ❌
humano2.accion() → flecha se creó dentro de accion → hereda humano2 → "Laura" ✅
Función NORMAL → this = quien está a la izquierda del . Función FLECHA → this = quien estaba a la izquierda del . cuando se CREÓ humano.normal() → normal ve a humano → "Pedro" ✅ humano.flecha() → flecha se creó en global → window.nombre → undefined ❌ humano2.accion() → flecha se creó dentro de accion → hereda humano2 → "Laura" ✅
🎓 Conclusión final
Scope = ¿Dónde vive la variable? → Ámbito léxico
Contexto/
this= ¿Quién ejecuta la función? → Depende de CÓMO se llamaFunción normal = Tiene su propio
this(peligroso en callbacks)Función flecha = No tiene
thispropio, usa el del padre (perfecta para callbacks)
💡 Tip práctico: Si ves
thisdentro de unsetTimeout,forEach, o evento, y no funciona como esperas… usa una función flecha.
// ❌ Problema común
setTimeout(function() {
console.log(this.nombre); // undefined
}, 1000);
// ✅ Solución con flecha
setTimeout(() => {
console.log(this.nombre); // funciona si el this padre existe
}, 1000);¿Quieres que profundice en algún caso específico? ¡Avísame!
Comentarios
Publicar un comentario