¿Qué son los contextos de ejecución y la cadena de alcances?
Los contextos de ejecución y la cadena de alcances son conceptos fundamentales en JavaScript, ya que determinan cómo y dónde se accede a las variables dentro del código. Al usar las palabras clave var, let, y const, es esencial comprender estas diferencias: el tipo de scope y el comportamiento de hoisting. Esto nos ayudará a tomar decisiones informadas sobre cuándo y cómo utilizar cada una.
¿Por qué es importante el scope en JavaScript?
El scope es crucial porque determina el alcance y la vida útil de una variable. Con var, las variables tienen un scope a nivel de función, mientras que let y const se limitan al bloque en el que se declaran. Esta distinción es vital para evitar errores y entender cómo se ejecuta el código.
Por ejemplo, consideremos el siguiente código:
const productName ="laptop";const price =899;const brand ="techCode";functiongetProductInfo(){const productName ="smartphone";const price =499;return`${productName} costs ${price} and is of brand ${brand}`;}console.log(getProductInfo());
Aquí, el console.log imprime "smartphone costs 499 and is of brand techCode". Las variables productName y price dentro de la función sobrescriben las del contexto global, mientras que brand se toma desde el exterior debido a la cadena de alcances.
¿Cómo funciona el contexto de ejecución?
En JavaScript, el contexto de ejecución puede pensarse como muñecas rusas: el contexto global es la muñeca más grande y los contextos locales son las más pequeñas dentro de ella.
Contexto global: Incluye todas las variables y código que está por fuera de funciones o bloques.
Contextos locales: Son los bloques definidos, por ejemplo, dentro de una función.
¿Cómo se determina el contexto en un código?
A través del uso de llaves { }, podemos identificar los bloques que delimitan los contextos locales. Todo lo que cae fuera de estos bloques pertenece al contexto global.
let userPoints =80;functionevaluatePoints(){if(userPoints <100){console.log("Below average");}else{console.log("Above average");}}console.log(evaluatePoints());
En el código anterior:
userPoints y console.log(evaluatePoints()) forman parte del contexto global.
evaluatePoints() es un contexto local que contiene su propio flujo de ejecución.
¿Qué es el scope chain o cadena de alcances?
La cadena de alcances define cómo JavaScript encuentra las variables. Un contexto local puede acceder a variables en contexto global, pero no al revés. La búsqueda de variables funciona de adentro hacia afuera, asegurándose de que no haya acceso entre contextos locales iguales.
¿Cuándo ocurre el error 'variable no definida'?
Esto ocurre cuando un contexto local busca una variable que no existe ni localmente ni en ningún contexto superior.
const globalVariable ="global1";functionlocal1(){console.log(globalVariable);// Accede correctamente a "global1"console.log(localVariable);// Error: localVariable no está definidafunctionlocal2(){const carrot ="🥕";console.log(`local2: ${carrot}`);}functionlocal3(){console.log(local3Variable);// Error aquí también}local2();local3();}console.log(local1());
En este ejemplo, intentar acceder a localVariable y local3Variable en contextos que no las definen o que no tienen acceso a ellas desencadena dichos errores.
Comprendiendo los errores de variable no definida
Es importante internalizar la restricción de que los contextos iguales no pueden comunicarse entre sí sin que compartan un contexto padre donde esté definida la variable de interés. Este entendimiento permitirá evitar múltiples errores en implementaciones más complejas, asegurando un manejo eficiente de cómo y dónde se posicionan y utilizan las variables.
Motívate a seguir profundizando en estos conceptos. La práctica y comprensión de cómo JavaScript maneja el scope y los contextos de ejecución te harán un desarrollador más hábil y capaz de escribir código más eficiente y sin errores.
En JavaScript, los contextos de ejecución y la scope chain son conceptos fundamentales que permiten comprender cómo se ejecuta el código y cómo se accede a las variables.
Contexto de ejecución:
Un contexto de ejecución es un entorno en el que se ejecuta el código JavaScript. Contiene información sobre el código que se está ejecutando, como las variables declaradas, las funciones y el objeto global. Cada vez que se invoca una función, se crea un nuevo contexto de ejecución.
Scope Chain:
La scope chain es el mecanismo que utiliza JavaScript para determinar qué variables están disponibles para una instrucción en particular. Se busca en una secuencia de contextos de ejecución hasta encontrar la variable con el nombre correspondiente.
Pasos para la búsqueda en la scope chain:
Objeto de activación actual: Se busca la variable en el objeto de activación del contexto de ejecución actual.
Entorno externo: Si no se encuentra la variable en el objeto de activación actual, se busca en el entorno externo, es decir, en el contexto de ejecución padre.
Repetición: El proceso se repite hasta encontrar la variable o llegar al objeto global.
Variable no definida: Si no se encuentra la variable en ningún contexto de ejecución, se genera un error de referencia. (Que eso fue justo lo que sucedio en el ejemplo final de la clase)
Conclusiones:
Los contextos de ejecución y la scope chain son conceptos esenciales para comprender el funcionamiento del código JavaScript.
Los contextos de ejecución definen el entorno en el que se ejecuta el código, mientras que la scope chain determina qué variables están disponibles para una instrucción en particular.
La comprensión de estos conceptos es fundamental para escribir código JavaScript claro, organizado y libre de errores.
Este tema es sin duda tan fascinante como importante en JavaScript, debajo les comparto mi resumen sobre esta lección!
resaltando por acá este importante cuadro, saludos!
Me surgió una duda en todo esto. Como puedo ejecutar solo una función de una lista de funciones dentro de una función contenedora ?
Como puedo ejecutar solo la función localTwo sin que se ejecute el primer console.log ni el localThree ?
Tal como está el código, no es posible ejecutar localTwo sin que se ejecuten el primer console.log ni el localThree.
Para poder ejecutar solo la función localTwo sin ejecutar el resto, lo mejor sería extraerla de localOne, y dejar localTwo en el contexto global. Y eso se ejecutaría sin problemas, ya que localTwo no utiliza nada del contexto local de localOne. Claro que su nombre y el texto del console.log perderían algo de sentido.
La otra opción obviamente sería comentar el primer console.log y la línea que ejecuta localThree.
Entonces no es posible 🤔. Me queda claro entonces que si quieres que tu función haga algo lo mejor es escribir ese código aparte. Gracias !
Mi ejercicio resuelto, el contexto local es lo que se encuentra dentro de las llaves y el contexto global es lo que se encuentra por fuera.
Del contexto global no se puede acceder al contexto local, pero del contexto local si se puede acceder al contexto global.
Las arrow functions en JavaScript permiten una sintaxis más corta para definir funciones. Usan la sintaxis () => {} y no crean su propio contexto de this; en su lugar, heredan el this del contexto donde fueron definidas. Esto es especialmente útil en callbacks, donde se necesita mantener el contexto de la función padre.
Ejemplo:
const obj ={value:42,getValue:function(){return()=>this.value;// 'this' se refiere a 'obj'}};const func = obj.getValue();console.log(func());// 42
En este caso, la arrow function no tiene su propio this, por lo que se obtiene el valor de value del objeto obj.
MIS APUNTES:
El contexto global incluye userPoints y el console.log final. El contexto local es todo lo que está dentro de las llaves de la función, incluyendo condicionales como el if.
El hoisting en JavaScript se refiere a cómo las declaraciones de variables y funciones son movidas a la parte superior de su contexto de ejecución antes de que se ejecute el código. Aquí tienes un ejemplo:
En este código, la declaración var myVar es "elevada" al inicio, por lo que el primer console.log no lanza un error, pero muestra undefined porque la asignación myVar = 5 aún no se ha realizado.
En JavaScript, no se pueden tener contextos locales dentro de otros contextos locales. Cada función crea su propio contexto local, pero los contextos locales no pueden anidarse. Sin embargo, desde un contexto local puedes acceder a variables de un contexto global, pero no al revés. Es como las muñecas rusas: puedes abrir y ver dentro de una muñeca, pero no puedes agregar muñecas nuevas dentro de otra muñeca del mismo tamaño. Así, cada función mantiene su propio alcance sin anidamiento adicional.
he creado un artefacto que ilustra varios aspectos importantes de los contextos de ejecución y la scope chain en JavaScript. Aquí están algunos puntos adicionales y observaciones sobre los ejemplos:
// Ejemplo 1: Contextos de ejecución y scope chain básicoslet globalVar ="Soy global";functionouterFunction(){let outerVar ="Soy outer";functioninnerFunction(){let innerVar ="Soy inner";console.log(innerVar);// Accede a variable localconsole.log(outerVar);// Accede a variable del contexto externoconsole.log(globalVar);// Accede a variable global}innerFunction();}outerFunction();// Ejemplo 2: Closures y scope chainfunctioncreateCounter(){let count =0;returnfunction(){return++count;}}const counter =createCounter();console.log(counter());// 1console.log(counter());// 2// Ejemplo 3: Hoisting y TDZ (Temporal Dead Zone)console.log(hoistedVar);// undefinedvar hoistedVar ="Soy hoisted";// console.log(tdz); // ReferenceErrorlet tdz ="Temporal Dead Zone";// Ejemplo 4: Scope en bloques (let y const){let blockVar ="Solo visible en este bloque";constBLOCK_CONST="Constante de bloque";}// console.log(blockVar); // ReferenceError// Ejemplo 5: This y contextos de ejecuciónconst obj ={method:function(){console.log(this);}};obj.method();// 'this' se refiere a 'obj'const unboundMethod = obj.method;unboundMethod();// 'this' se refiere al objeto global (en modo no estricto)// Ejemplo 6: Modificación del scope chain con 'with' (no recomendado)const withObj ={x:10,y:20};with(withObj){console.log(x + y);// 30}// Ejemplo 7: Módulos y scope// file1.jsexportconst moduleVar ="Soy del módulo";// file2.jsimport{ moduleVar }from'./file1.js';console.log(moduleVar);// Notas adicionales:// - Cada función crea su propio contexto de ejecución.// - Los contextos de ejecución forman una pila (call stack).// - La scope chain se crea cuando se define una función, no cuando se ejecuta.// - Las arrow functions no crean su propio 'this', heredan el 'this' del contexto circundante.
Si a algunos de ustedes les quedó un poco de duda sobre las palabras claves var, let y const. Les recomiendo mucho que lean esta guía, despejará sus dudas. 👌👌 Variables en JavaScript – Guía para principiantes sobre var, const y let
Buena onda, gracias. Me sirvio mucho.
# **Scope (Ámbito) en JavaScript**
El **scope** o **ámbito** determina dónde puedes acceder a una variable dentro de tu código. Dependiendo de dónde y cómo se declara una variable, su scope puede ser global, de función (local), de bloque, o del módulo.
Si haces referencia a una variable, el motor de JavaScript buscará su declaración en el **entorno** más cercano, y seguirá buscando en entornos más lejanos hasta llegar a la línea de código que la **variable esté declarada**, pero no en viceversa. A este proceso se lo denomina **cadena de scope** *(scope chaining)*.
## **Tipos de Scope en JavaScript**
1. **Scope Global**: - Las variables declaradas fuera de cualquier función o bloque tienen un ámbito global. - Las variables globales son accesibles desde cualquier parte del código, incluidos dentro de funciones y bloques. jsx javascriptCopiar código *let* globalVar = "Soy global"; *function* mostrarGlobal() { console.log(globalVar); // "Soy global" } mostrarGlobal(); console.log(globalVar); // "Soy global" 2. **Scope de Función (Local)**: - Las variables declaradas dentro de una función tienen un ámbito local, es decir, sólo son accesibles dentro de esa función. - No se puede acceder a estas variables fuera de la función. jsx javascriptCopiar código *function* mostrarLocal() { *let* localVar = "Soy local"; console.log(localVar); // "Soy local" } mostrarLocal(); console.log(localVar); // Error: localVar no está definida 3. **Scope de Bloque**: - Con la introducción de let y const en ES6, las variables pueden tener un ámbito de bloque. - Las variables declaradas con let o const dentro de un bloque ({}) sólo son accesibles dentro de ese bloque. jsx javascriptCopiar código if (true) { *let* blockVar = "Soy un bloque"; console.log(blockVar); // "Soy un bloque" } console.log(blockVar); // Error: blockVar no está definida 4. **Scope de Módulo** (ES6 y posteriores): - En el contexto de los módulos de JavaScript (archivos .js importados/exportados), las variables declaradas en un módulo tienen un ámbito de módulo. - No son accesibles fuera del módulo a menos que se exporten. jsx javascriptCopiar código // modulo1.js *let* moduloVar = "Soy un módulo"; export default moduloVar; // main.js import moduloVar from './modulo1.js'; console.log(moduloVar); // "Soy un módulo"
### **Hoisting y Scope**
- **Hoisting**: Es el comportamiento de JavaScript donde las declaraciones de variables y funciones se mueven "arriba" de su scope antes de la ejecución del código. Esto significa que puedes usar variables y funciones antes de declararlas, aunque su valor será undefined si son variables. jsx javascriptCopiar código console.log(x); // undefined *var* x = 10; - En el caso de let y const, aunque son hoisted, no se pueden utilizar antes de su declaración debido a lo que se llama "zona temporalmente muerta" (Temporal Dead Zone, TDZ).
Es lo que pude hacer de lo que entendi
Por lo que entendi, los contexti de ejecucion es un entorno en el que se ejecuta un fragmento del codigo, y el alcance que tiene cada variable, a mi manera de ver, si quieres establecer variables globales fijas seria mejor usar var directamente ya que su alcance lega a funcion
Buen ejemplo y muy entendible...
estuvo facil si calcule bien la salida sin usar editor
Scope y Ciclo de Vida de las Variables en JavaScript
El scope (alcance) de una variable en JavaScript determina en qué partes del código puede ser accedida, y está directamente relacionado con su ciclo de vida, es decir, desde su creación hasta su destrucción en memoria.
1. Scope Local (por Función) y Variables con var
Las variables declaradas con var dentro de una función tienen alcance local a la función. Esto significa que solo son accesibles dentro del cuerpo de dicha función y no pueden ser referenciadas fuera de ella.
functioncalcularTotal(){var productName ="Laptop";var price =1200;console.log(productName, price);// Acceso válido}calcularTotal();// console.log(productName); // Error: productName is not defined
En este caso, productName y price tienen un ciclo de vida limitado a la ejecución de calcularTotal(). Una vez finalizada la función, las variables son destruidas (a menos que formen parte de un closure)
Es genial poder tener mayor comprensión sobre el funcionamiento de los contextos. Al inicio pensaba que podían comunicarse entre contextos locales.
Ya me queda claro que entonces si la variable no está definida dentro del contexto local, en vez de buscarla en otro contexto local de igual jerarquía, se saltaría directamente a un contexto de mayor jerarquía.