Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Block Scope

5/12
Recursos

Aportes 144

Preguntas 21

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Tuve curiosidad de por que al instructor cuando ejecutaba la función llamada anotherFunction con un for inicializado con la palabra reservada var se mostraba el numero diez en consola, entonces decidí investigar un poco; la respuesta tiene que ver con el Hoisting y Asincronía o EventLoop.
.
Esto es algo como lo que tiene el instructor:

function functionName() {
	// Para este ejemplo declarare que el for solo de 3 "vueltas", es decir la condición sera: i < 3.
	for(var i = 0; i < 3; i++) {
		setTimeout(function() {
			console.log(i);
		}, 1000);
	}
	
	console.log('El valor final de "i" es: ' + i);
}

El hoisting hace que la variable con el nombre i dentro del for se “eleve” y sea asignada en memoria, por lo tanto a lo último se estará reasignando el ultimo incremento que tuvo y se podrá acceder a ella en cualquier punto dentro de la función functionName.

function functionName() {
	var i;
	for(i = 0; i < 3; i++) {
		setTimeout(function() {
			console.log(i);
		}, 1000);
	}
	// Este console.log podra acceder a i aun afuera del for, esto por que la variable i fue declarada y asignada antes que todo en tiempo de ejecución (hoisting).
	console.log('El valor final de "i" es: ' + i);
}

Entonces asumiendo eso y respondiendo a la pregunta de por que el console.log que esta adentro del setTimout solo imprime el valor final de i llegue a la siguiente conclusión:
.

  1. El for estará ejecutándose en el Call Stack mientras la condición propuesta en el for (i < 3) se cumpla, por tanto también se ejecutara el setTimeout cada que la condición del for sea verdadera, sin embargo hay que recordar que el setTimeout es una función del navegador, entonces el setTimeout pasara a ejecutarse en “segundo plano” y una vez que los tiempos de espera definidos de los setTimeout se cumplan, estos pasaran al Callback Queue.
    .
  2. Una vez que la condición del for ya no se cumpla, pasara a ejecutar el console.log que mostrará el valor final que para entonces será igual a 3 por que el for ya estuvo mutando el valor con cada incremento (i++).
    .
  3. Posteriormente ya cuando el Call Stack esta vació pasaran a ejecutarse el callback de cada setTimeout que a su vez ejecutan un console.log imprimiendo el valor de la variable i, recordando que i ya tiene el valor final de 3 por que se había incrementado en uno en cada “vuelta” que daba el for.
    .

    .
    Referencias:
    JavaScript closure inside loops – simple practical example

    Is it best to use “var” or “let” in for loop iterations or does it even matter?
    .

El block scope gue algo que me rompió cuando lo aprendí, porque si no me equivoco, no hay más lenguajes que lo tengan jaja (o igual si) pero aún no los conozco

Para explicar un poco mejor qué fue lo que sucedió con el timeOut, al declarar con “var” la variable “i” dentro del for, lo que estamos haciendo es declarar una variable global llamada “i”, y con cada iteración del for estamos sobreescribiendo esa variable, el for del 1 al 10 se ejecuta en menos de un segundo, es decir, una computadora es rápida ejecutando código, pero el setTimeout se ejecutará después de un segundo, JavaScript NO se va a quedar esperando que cada setTimeout se ejecute, simplemente JavaScript va a ver que hay un setTimeout y lo va a poner en su cola de tareas (Ver el curso de asíncronismo con JavaScript y el curso profesional de JavaScript para entender esto mejor), el caso es que, cuando pasa un segundo, los 10 setTimeouts que JavaScript puso en cola (Uno por cada iteración) se ejecutan, y como “i” es una variable global que fue sobreescrita, se quedo con el último valor de 10 (Porque aunque la condición del último ciclo no se cumplió, la variable si fue asignada para poder evaluar la condición), y es por eso que todos los setTimeouts miran el valor de la variable y todos acaban obteniendo “10”, con let, como saben, no se puede sobreescribir la variable, y tenemos un “let” diferente por cada iteración (Imaginen que cada iteración es un bloque de código totalmente diferente), entonces, cada setTimeout agarra el “let” que está dentro de su propio bloque de código, y como es único gracias al scope, ahí si que se imprimen del 1 al 9:D!

Un videíto increíble de var, let y const por si gustan entender mejor el scope

.

https://www.youtube.com/watch?v=ojrvxYcKeYg

Les dejo esta infografia como breve resumen de lo que es el Scope. espero sea util 😃

Con var , tiene un scope de función y solo un enlace compartido para todas sus iteraciones de bucle, es decir, i en cada callback setTimeout significa la misma variable que finalmente es igual a 6 después de que finaliza la iteración del bucle.

Con let tener un scope de bloque y cuando se utiliza en el ciclo for obtiene un enlace nuevo para cada iteración, es decir, el i en cada callback setTimeout significa una variable diferente, cada una de las cuales tiene un valor diferente: la primera es 0, la el siguiente es 1 etc.

Ahora, ¿Pero por qué me devuelve 10 veces 10? ¿No debería devolverme 10 veces 9?
veamos la declaración del ciclo for:

for (var i = 0; i < 10; i++) {
	...
}

El ciclo for termina cuando la condición (i < 10) sea falsa, osea que mientras sea verdadera el recorrerá el ciclo. La variable i aumentará su valor en 1 (i++) por cada iteración, osea que tomará estos valores: (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10). Toma el 10 porque es ese el valor donde la condición (i < 10) es falsa puesto que 10 no es menor que 10, si no que es igual… y el ciclo termina.
Espero haberles ayudado y que hayan aclarado sus dudas!

Si todavía se les complica entender, les dejo el enlace de la explicación del profesor Richard!!

A mi me sirvio entenderlo asi
recordemos que al declarar una variable con var esta puede reevaluarse con otro valor y que cuando declaramos una variable lo que estamos haciendo es decirle a la computadora “guardeme este valor en memoria” , entonces cuando paso al console.log(i) lo que hizo fue enviar esta orden a una “lista de tareas” que se ejecutara cuando ya termine de leer todo el codigo.
Entonces cada que realizaba un ciclo, este le decia " mandeme esta funcion a la lista de tareas y la ejecuta ahorita" entonces teniamos 10 veces console.log(i) en espera, cuando termino de ejecutarse todo el codigo, este le dijo a memoria “Cuanto es el valor de i?” y como se declaro con var, fue como si se estuviera reescribiendo en cada ciclo, entonces en memoria lo unico que tenia era que i = 10, por eso imprimio 10 veces el mismo valor.
Ahora ¿Qué pasa con let?¿Por qué si funciona con esto?
Realiza exactamente lo mismo ciclo, pero esta vez en memoria, hay 10 numeros guardados por que let solo permite definir una variable con un valor, no permite reevaluarla, entonces se ejecuto el primer console.log(i) este tomo el primer valor de i que era 1 y luego ocurrio lo mismo con los demas console, pasando uno a uno los valores de i

Espero le sirva a alguien

Dentro de una función podemos tener un bloque de código, por ejemplo: un if, mientras lo llamamos sobre una llave estará guardado dentro de un bloque.

Si definimos un elemento con var podemos acceder en todos los elementos de la función, si lo llamamos fuera del bloque donde está, vamos a poder acceder a ese elemento.

Con let y const no vamos a poder acceder a ellos porque se establecen dentro del bloque, solo se puede acceder a ellos dentro de ese bloque.

muy importante y ultil el uso de let.

const fruit = () => {
    if (true) {
        //De esta forma puedo acceder a las variables declaradas dentro del IF, se puede acceder a ellas fuera del IF
        // var fruit1 = 'Apple';
        // var fruit2 = 'Banana';
        // var fruit3 = 'Kiwi';
        //cuando declaro las variables con LET y/o CONST dentro del IF, son locales para el bloque de codigo del IF
        //y no las puede acceder fuera del bloque IF, asi esten en la misma funcion
        var fruit1 = 'Apple';
        let fruit2 = 'Banana';
        const fruit3 = 'Kiwi';

        console.log(fruit2);
        console.log(fruit3);
    }

    console.log(fruit1);
    // console.log(fruit2);
    // console.log(fruit3);

    //para poder acceder a las variables fruit2 y fruit3, debo colocarlas dentro del bloque de codigo donde fueron declaradas , en este caso IF
}

fruit();

// //Esta variable esta en ambito globa,
// let x = 1;
// {
//     //esta variable esta en ambito local, 
//     //y asi tenga el mismo nombre de la del ambito local, mantienen cada una su valor
//     let x = 2;
//     console.log(x);
// }
// console.log(x);

var x = 1;
{
    //esta variable esta en ambito local, 
    //y asi tenga el mismo nombre de la del ambito local, 
    //la asignacion hecha del ambito local se transfiere a la variable global
    var x = 2;
    console.log(x);
}
console.log(x);


// De esta forma solo muestra el valor diez, aunque lo muestra 10 veces, 
//esto ocurre porque nos muestra el ultimo valor de la variable
// dentro del ambito del ciclo for esta asignado el diez.
// const anotherFunction = () => {
//     for (var i = 0; i < 10; i++) {
//         setTimeout(() => {
//             console.log (i);
//         }, 1000)
//     }
// };

//al cambiar la forma de asignacion de declaraciòn de la variaable dentro del FOR,
//y usar LET, no muestra el resultado esperado.
const anotherFunction = () => {
    for (let i = 0; i < 10; i++) {
        setTimeout(() => {
            console.log (i);
        }, 1000)
    }
};

anotherFunction();

Resumen del scope con var, let y const.

En for no debemos utilizar var i = 0 porque al imprimir va imprimir 10 veces el ultimo valor, ejemplo:

//for no debemos utilizar var sino let
const anotherFunction = () => {
  for (var i = 0; i < 10; i++) {
    setTimeout(() => {
      console.log(i)
    }, 1000)
  }
}
anotherFunction()

Va imprimir: 10 10 10 10 10 10 10 10 10 10
**Pero con let: **

const anotherFunction = () => {
  for (let i = 0; i < 10; i++) {
    setTimeout(() => {
      console.log(i)
    }, 1000)
  }
}
anotherFunction()

Va imprimir: 0 1 2 3 4 5 6 7 8 9

JavaScript setTimeout y curiosidades
La función de JavaScript setTimeout se encarga de ejecutar otra función después de un tiempo determinado . Se suelen usar para gestionar animaciones , transiciones y operaciones similares. Vamos a construir el ejemplo de “hola mundo”.

function mensaje() {
console.log(“hola desde javascript”);
}
setTimeout(mensaje,5000);

Este mensaje se ejecutará pasados 5 segundos en la consola:

https://platzi.com/clases/1807-scope/25874-block-scope/?time=417 Esta fue una pregunta de entrevista de screening, define la salida de una ciclo usando var y let dentro de un setTimeout ¿cual es la salida? 😉

Oscar lo explica perfecto pero por si gustan otro ejemplo adicional recomiendo este video: https://youtu.be/kQwaq2MMZ-Y

Pesima la explicacion que dio sobre el for con el setTimeout. PESIMA!, lamentandolo mucho son muy pocos los cursos de platzi que en verdad explican el como y no solo el resultado.

Cuando declaramos una variable tipo var dentro de una función su scope va a poder ser accedido desde cualquier bloque dentro de la función. Let y const por otro lado solo funcionaran dentro del bloque declarado.

Platzicompas, les comparto algunas notas de la clase:
.

.
Espero les ayude.
(⌐■_■)

sigo sin entender el ejemplo del for y el setTimeout.

traté de ejemplificarlo en mi cabeza llevándol al proceso que haría el engine de JS (callstack, callback queue, event loop, etc), pero me sigue sin cuadrar algunas cosas

Siempre let nunca inlet😁

Por si alguien necesita tener mas claro el temas les dejo este link https://www.youtube.com/watch?v=cTfGyVFrLxQ&t=29s

supongo que este imprime 10 veces el 10 porque espera al código por el setTimeOut lo que significa que primero ejecuta la función del for, y esta al ser ejecutada pues va a ir sobrescribiendo sus variables, primero var i equivale 0 después 1 después 2 hasta llegar a 10, después de esto ejecuta el setTimeOut del console.log osea el 10 y de nuevo vuelve a hacer este paso vuelve al for sobreescribe las variables y ejecuta el 10 y asi hasta ejecutarlo las 10 veces. pueden hacer la prueba quitando el setTimeOut con el var y notaran que si imprime el ciclo de la manera correcta.

Una buena forma de entender el problema del ciclo for, es entendiendo los procesos asincrónicos de Javascript, pásense por el curso de fundamentos de javascript y ahí explican muy bien este tema

me exploto la cabeza con el ejemplo del for 😮

const fruits = () => {
    if (true) {
        var fruits1 = 'apple';
        let fruits2 = 'banana';
        const fruits3 = 'kiwi';
    }
    console.log(fruits1);
    console.log(fruits2);
    console.log(fruits3);
}

fruits();

/* en este caso puedes acceder a la variable fruits1 por que fue declarada con var dentro del bloque if, con var es posible tener un scope global dentro de un bloque de codigo, sin embargo con let y const pasa algo diferente y es que cuando estan dentro de un bloque de codigo su scope local se limita al interior del bloque en este caso dentro del if */

const fruits = () => {
    if (true) {
        var fruits1 = 'apple';
        let fruits2 = 'banana';
        const fruits3 = 'kiwi';
        console.log(fruits2);
        console.log(fruits3);
    }
    console.log(fruits1);
    
}

fruits();

/* en este caso si puedes acceder a todas las variables ya que los console.log() se estan ejecutando dentro de un scope valido para cada una de las variables. */

let x = 1;
{
    let x = 2;
    console.log(x);    
}
console.log(x);

/* En este caso no tenemos error de sintaxis por tener dos variables let con el mismo nombre x ya que la segunda x esta dentro de un bloque de codigo y JS lo toma como una variable diferente, por lo tanto el console.log(x) dentro del bloque te muestra el valor de 2 mientras que el console.log(x) fuera del bloque no puede acceder al bloque y toma el valor de la x declarada fuera del bloque de esta manera funciona ya que let y const limitan su scope dentro de un bloque cuando estan dentro de el. */

var x = 1;
{
    var x = 2;
    console.log(x);    
}
console.log(x);

/* mientras que con var nos mostraria como resultados en ambos console.log(x) el 2, por que var no limita a scope local cuando se encuentra dentro de un bloque y lo que hace es reasignarle el valor a la x que esta por fuera del bloque. */

const anotheFunction = () => {
    for (var i = 0; i < 10; i++) {
        setTimeout(() => {
            console.log(i);    
        }, 1000)
    }
};

anotheFunction();

/* cuando usamos var el ciclo se sigue ejecutando y como var reasigna valores a cada variable i para cuando pase el segundo todas la variables i dentro de la pila de ejecucion tendran asignado el ultimo valor osea 10 */

const anotheFunction = () => {
    for (let i = 0; i < 10; i++) {
        setTimeout(() => {
            console.log(i);    
        }, 1000)
    }
};

anotheFunction();

/* mientras que con let la variable i de cado ciclo seran variables diferentes y se iran mostrando en el orden de la pila de ejecucion respetando el valor que se le asigno a i en su respectivo momento */

Lo que entiendo por bloque en JS es todo aquello que esté entre llaves {}

Un pequeño repaso de los cursos de básico y fundamentos de javascript

Entonces podríamos ahorrarnos todo esto simplemente usando let y const :3

var es un rebelde sin causa, le sabe a cake las delimitaciones por bloque! 😂

Ok!! no sabía eso de quel scope del var aplica dentro de una función y que el scope del let y const aplica dentro de un bloque, mind blowing!

por lo que entendí, las variables declaradas con var no toman en cuenta el scope de un bloque y se lo “saltan” por así decirlo y lo que hacen es asignar su scope a la función mas cercana o si no existe una función lo hace de manera global.

Para terminar de complementar este modulo del Scope en JS, les recomiendo mucho el video de Sasha en su canal Cocina del codigo, aunque Oscar lo explica bien, tiene pequeñitos errores que puede confundir a un principiante, en su lugar Sasha lo explica de una manera mucho mas didactiva y dinamica, lo cual es mejor visualmente con ejemplos y referencias claras. Les he dejado el video arrriba en el texto, ‘La cocina del codigo’.

Cuando vi el for y que siempre retornaba “10” no entendia que es lo que estaba pasando. Por eso me puse a buscar y a repasar conceptos de EventLoop y Hoisting.
Les comparto unas pruebas que hice de esto mismo que practicamos en la herramienta “loupe” de la pagina de latentflip .
Este ejemplo lo hice solo con 3 vueltas de loop.

function otraFuncion(){
    for (var index = 0; index < 3; index++){
        setTimeout(function imprimirIndice(){ 
                console.log(index)
            }, 1000)
    }
}
otraFuncion();

–

  1. Esta es la prueba usando var en el for. Cuando empieza a ejecutar las tareas del Callback Queue toma el ultimo valor asignado (el del ultimo loop, en este caso “2”) y lo imprime 3 veces.

–

  1. Esta es la prueba usando let en el for. En este caso imprime los indices correctamente, sin pisar el valor de ninguno de ellos.

IMPORTANTE ACLARACIÓN:: var si afecta fuera de los bloques, por lo que puede afectar nuestras aplicaciones.

Por esto es recomendable usar let o const

🧐 luego de haber visto el vídeo más de 2 veces, ejecutado el código un par de veces más, visto los vídeos compartidos por los compañeros de otros canales explicando las diferencias entre var, let y const, y otra vez ejecutado el código con sus variaciones en Chrome y utilizando el devtools con breakpoints … una cosa y solo una me queda claro:

NO HAY QUE USAR VAR! 🤪

(alguien que me explique porqué en el ejm, el índice definido con var, imprime las tantas veces el último valor del ciclo!!!) 🤯

Les dejo el código de la clase.

const fruits = () =>{
    if(true){
        //Cuando declaramos estas variables con var, podemos acceder a ellas
        //fuera del if, dentro del scope de la función
        // var fruits1 = 'apple';
        // var fruits2 = 'banana';
        // var fruits3 = 'kiwi';
        //En cambio cuando las declaramos con let, no podemos acceder a ellas
        //fuera del bloque del if
        let fruits1 = 'apple';
        let fruits2 = 'banana';
        let fruits3 = 'kiwi';
    }
    console.log(fruits1);
    console.log(fruits2);
    console.log(fruits3);
}

fruits();

//Lo que sucede acá es que el console.log dentro de bloque muestra lo que se asigna a la variable que está en el mismo scope.
let x = 1;
{
    let x = 2;
    console.log(x);
}
console.log(x);

//El mismo ejemplo pero cambiando los let por var
//Dentro del bloque de código se reasigna el valor de x, dando como resultado que los dos console.log muestren el último valor asignado de la variable, en este caso 2.
var x = 1;
{
    var x = 2;
    console.log(x);
}
console.log(x);


//Se ejecuta el número 10, esto por razón del hoisting, esto se puede solucionar cambiando var por let.
const anotherFunction =() =>{
    for (var i = 0; 1 < 10; i++){
        setTimeout(() => {
            console.log(i);
        }, 1000);
    }
}

anotherFunction();```

En pocas palabras, la palabra reservada var se debe dejar de usar y solo usar let y const

Block Scope
A diferencia del scope local este scope está limitado al bloque de código donde fue definida la variable. Desde ECMAScript 6 contamos con los keyword let y const los cuales nos permiten tener un scope de bloque, esto quiere decir que las variables solo van a vivir dentro del bloque de código correspondiente.

BLOCK SCOPE APUNTES

//Bloque de codigo es aquel que esta establecido dentro de unas llaves {}

const fruit = () => {

    if(true){

        var fruits = 'apple';
        var fruits2 = 'banana';
        var fruits3 = 'kiwi';

    }

    //vamos a acceder a las variables del if fuera del bloque del if
    console.log(fruits,fruits2,fruits3); // apple banana kiwi

    //---Cuando definimos variables en un bloque distinto con var

    /* Podre acceder a las variables sin problema alguno y podremos accederlos
       Ya que estan establecido dentro del scope de la funcion y esto significa
       El que podamos accederlos en cualquier parte del scope de la funcion */

    // Con let y const

    // No podremos acceder a ellas si estan establecidas con let y const
    // Porque ellas se establecen dentro del bloque en el que estan y solo
    // podran ser accedidas dentro de ese bloque
}

fruit()

let x = 1;

{

    let x = 2;
    console.log(x); //2
}

    console.log(x); //1

//Mismo ejemplo con var 

var x = 1;

{
//Lo que sucede aqui es que el valor reasignado a x tambien cambio en la variable global
// Si queremos declarar un valor debemos hacerlo con let para que este valor
  // trabaje solo en el scope de ese bloque 
    var x = 2;
    console.log(x); //2
}

    console.log(x); //2

const anotherFunction = () => {


    for(let i = 0; i < 10; i++){

        setTimeout(()=>{

            console.log(i);
        }, 1000)


    }
}

anotherFunction(); // al  imprimir la variable i que esta declarada con var
                    // IMPRIME 10 LAS 10 VECES
// Nos muestra este valor ya que esta accediendo al ultimo valor que recorre 
// El for

// La solucion es asignando la variable i con let```

RECOMENDADOS
VAR vs LET vs CONST: TODAS LAS DIFERENCIAS | JS en ESPAÑOL video
VAR, LET o CONST: ¿CUÁL DEBERÍA USAR? | JS en Español video

Este es el código para imprimir el valor de i cada segundo

const delay = (ms) => new Promise((res) => setTimeout(res, ms));
const anotherFunction = async () => {
    for (var i = 0; i < 10; i++) {
        await delay(1000);
        console.log(i);
    }
};
anotherFunction();

Es excelente el ejemplo que se ha dado esta clase con el for dentro de anotherFunction() para entender lo que se define como call stack y callback queue. Adicional a lo explicado (de manera increíble) por pabloverduzco, les tengo esta documentación que me ayudo a entender lo que estaba sucediendo: https://felixgerschau.com/javascript-event-loop-call-stack/

En esta clase vamos a fortalecer nuestros conocimientos en el Local Scope utilizando la otra variante de este ámbito, que es el scope en bloque. Para ello trabajaremos con una función y dentro de esta crearemos un bloque de código.

  • Ejemplo 1

    En la función crearemos un bloque de código (un if) y asignaremos una variables, ya fuera de este bloque mandaremos a llamar nuestras variables. La palabra reservada var tiene un alcance global dentro de toda la función, es decir, podemos llamar la variable fuera del bloque de código y aún así el scope de la función la reconocerá.

    //1. Creamos la función
    const fruits = () => {
      if (true) {
    		//Declaramos las variables
    		//var tiene un alcance en toda la función
        var fruit1 = "Manzana";
        var fruit2 = "Pera";
        var fruit3 = "Limon";
      }
      console.log(fruit1);
      console.log(fruit2);
      console.log(fruit3);
    //imprimimos el valor en consola
    };
    
    fruits();
    
    //Resultado 
    // > Manzana
    // > Pera 
    // > Limón
    

    La función trabaja sin ningún problema ya que como mencioné antes la función puede acceder a la variable var dentro del bloque de código, pero que pasaría si lo hacemos con let y const?

    const fruits = () => {
      if (true) {
        var fruit1 = "Manzana"; //alcance de toda la función 
        let fruit2 = "Pera"; //alcance dentro del bloque
        const fruit3 = "Limon"; //alcance dentro del bloque
      }
      console.log(fruit1);
      console.log(fruit2);
      console.log(fruit3);
    };
    
    fruits(); 
    
    //Resultado 
    // > Manzana
    // ERROR
    

    Ocurre un error ya que las variables declaradas con let y const solamente tienen un alcance dentro del bloque de código, y no pueden ser llamadas fuera de este (así esté en la misma función) para trabajar con estas variables necesariamente tiene que ser dentro del mismo bloque de código. Por lo tanto haríamos lo siguiente

    const fruits = () => {
      if (true) {
        var fruit1 = "Manzana"; //alcance de toda la función
        let fruit2 = "Pera"; //alcance dentro del bloque de código
        const fruit3 = "Limon"; //alcance dentro del bloque de código
    		//llamamos las variables DENTRO del bloque
        console.log(fruit2); 
        console.log(fruit3);
      }
      console.log(fruit1); //a esta la podemos llamar fuera
    };
    
    fruits();
    //Resultado
    // > Manzana
    // > Pera
    // > Limón
    

    Y listoo, ahora vemos como se comportan las variables en este scope de bloque

  • Ejemplo 2

    Para entender mejor el concepto en este ejemplo declararemos una variable global y luego otra dentro de un bloque de código y veremos que pasa

    let x = 1; //variable scope global
    {
      let x = 2; //esta variable solo es accesible dentro del bloque de código
      console.log(x);
    }
    console.log(x);
    
    // > 2 //block scope
    // > 1 //global scope
    

    Como vemos, JavaScript primero ejecuta el primer console.log con el valor de nuestra variable que está en el bloque de código, pero esta declaración solo existió dentro del bloque por lo tanto no le reasigna un valor a la variable global sino que sigue siendo la misma.

    Ahora, ¿que pasaría si utilizamos este mismo ejemplo pero lo trabajamos con la palabra reservada var?

    var x = 1; //variable scope global
    {
      var x = 2; //esta variable afectará el valor de la global
      console.log(x);
    }
    console.log(x);
    
    // > 2 //block scope que trasladó el valor a global
    // > 2 //global scope
    

    La palabra reservada var no respeta este scope de bloque sino que traslada el valor que se le asignó en el bloque a la variable global, reasignandole un valor. Debemos tener mucho cuidado y no usar var cuando queremos que un valor exista solo dentro de un bloque de código, y en vez de eso usar let.

  • Ejemplo 3

    Vamos a crear una función que va a trabajar sobre un loop y como vamos a mostrar elementos en basados en la asignación del scope que nos da var y let dentro del bloque. Para eso crearemos nuestra función que tendrá un loop y dentro del loop entonces se colocará un setTimeOut que nos permite ejecutar una función cada vez por intervalo de tiempo y la llamaremos.

    const anotherFunction = () => {
      for (var i = 0; i < 10; i++) {
        setTimeout(() => {
          console.log(i);
        }, 1000);
      }
    };
    
    anotherFunction();
    
    //Resultado 
    // 10
    // 10
    // 10
    // 10
    // 10
    // 10
    // 10
    // 10
    // 10
    // 10
    

    Podemos ver que ejecuta 10 veces el código y nos muestra el valor de “10”, esto ocurre porque recoge el último valor asignado sobre la variable i en este ámbito 10 y como i en este caso fue declarado con var y es una variable global el valor de 10 siempre se reasigna y por lo tanto es un valor fijo. Esto no debería ocurrir, ya que deberíamos ver lo que ocurre durante cada iteración. Para solucionar esto, cambiaremos la palabra reservada var por let y lo que ocurrirá es que por cada iteración se guardará el nuevo valor en un nuevo let (que no se reasignará cada vez) y por lo tanto nos mostrará el siguiente resultado, que es el esperado.

    const anotherFunction = () => {
      for (let i = 0; i < 10; i++) {
        setTimeout(() => {
          console.log(i);
        }, 1000);
      }
    };
    
    anotherFunction();
    
    //Resultado 
    // 0
    // 1
    // 2
    // 3
    // 4
    // 5
    // 6
    // 7
    // 8
    // 9
    

La verdad prefiero no utilizar var en lo posible.

No usen var!

Moraleja: Dejar de usar var y en adelante utilizar const y let.
Bloque de código: toda porción de código encerrada entre llaves {}

sí hasta aquí tienes algunas dudas. Sugiero complementarlo con el video de sasha en el que habla todo acerca de Scope https://www.youtube.com/watch?v=s-7C09ymzK8

Ojala la vida fuera tan fácil como este curso…

Var dentro de los bloques de código siempre toma como valor la última declaración hecha.
Mientras que let y const no se reescriben.

Entonces a ver si entendí: con var lo que sucede es que debido al hoisting el interprete eleva a la variable declarada con var, esta queda guardada en el scope global teniendo un mismo entorno léxico y por cada iteración del for el valor se actualiza y cuando el setTimeOut se ejecuta toma el último valor (10).
Y con let lo que está sucediendo es que cada valor que toma “i” es un entorno diferente entonces al ejecutarse el setTimeOut toma el valor en ese momento de la variable “i” que corresponden a distintos momentos del código.
Algo más para agregar? Alguna corrección a lo que escribí?

El scope de bloque esta delimitado por las llaves, por ejemplo, el bloque de código de un if.
Para usar el scope de bloque se debe declarar la variable con let o const, de lo contrario, con var se podrá acceder a la variable en un scope global.
Con var, además de poder acceder a la variable de forma global, también es posible cambiar el valor de forma global. Por ejemplo, si cambiamos el valor de la variable x dentro de un bloque de código, el valor también cambiará fuera del bloque.

Para profundizar más sobre este tema les recomiendo este enlace https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/scope%20%26%20closures/ch5.md que hace parte del libro You Don’t Know JS

const fruit = ()=> {
/*
    Para el scope de bloques debemos de tener en cuenta que si manejamos las variables 
    con la palabra reservada var obtendremos como resultado la referencia a una variable
    local a la funcion (en este caso fruit) pero, si declaramos variables con let
    obtendremos como resultado una referencia a una variable local al bloque, es decir
    terminando el bloque de ejecucion (en este caso el condicional if), la variable deja de existir
*/

    if(true){
        var manzana = "manzana";
        let pera = "pera";
        const guayaba = "guayaba";
    }

    console.log(manzana);
    console.log(pera);
    console.log(guayaba);
}
const fruits = () => {
    if(true){
        var fruits1 = 'apple';  // scope global
        let fruits2 = 'banana'; // scope de bloque
        const fruits3 = 'kiwi'; // scope de bloque
    }
    console.log(fruits1);
    console.log(fruits2);
    console.log(fruits3);
}

fruits();```

¿Qué es un bloque en JS?


Mientras llamemos sobre una llave esa variable va estar guardada dentro de un bloque, puede ser una function, un if, for, etc…

Si ejecutamos la siguiente función al ser declaradas con var vamos a poder acceder a los valores de esas variables fuera del bloque, ya que var es una asignación del scope local dentro de la function.

const fruits = () => {
    if (true) {
        var f1 = 'apple'
        var f2 = 'banana'
        var f3 = 'kiwi'
    }

    console.log(f1)
    console.log(f2)
    console.log(f3)
}

fruits();

Pero con let y const no vamos a poder acceder, ya que estos se establecen dentro del bloque.

const fruits = () => {
    if (true) {
        var f1 = 'apple'
        let f2 = 'banana'
        const f3 = 'kiwi'
    }

    console.log(f1)
    console.log(f2)
    console.log(f3)
}

fruits();

Para que funcione el anterior código tiene que ser declarado así:

const fruits = () => {
    if (true) {
        var f1 = 'apple';
        let f2 = 'banana';
        const f3 = 'kiwi';
        console.log(f2)
        console.log(f3)
    }
    console.log(f1)
}

fruits();

También podemos asignar una variable con el mismo nombre y no dar error cuando una esta en el scope global y otra dentro de un bloque

let x = 1
{
    let x = 2
    console.log(x)
}
console.log(x)

Al declarar la variable del for con var y tratar de visualizar el valor de está, veremos que nos muestra el último valor que recorre nuestro for. La solución más simple para esto es asignar la variable let para ese scope de bloque

const anotherFunction = () => {
    for (var i = 0; i < 10; i++) {
        setTimeout(() => {
            console.log(i)
        }, 1000)
    }
}
anotherFunction()

const anotherFunction = () => {
    for (let i = 0; i < 10; i++) {
        setTimeout(() => {
            console.log(i)
        }, 1000)
    }
}
anotherFunction()

Scope bloque
Este scope solo funciona con let o const, este scope permite su alcance dentro del bloque en el que se instancia ya sea un bucle, un if o un bloque forzado (las llaves puestas solas {} con el único propósito de generar un nuevo scope)
P.D. las variables declaradas en los parámetros de una función o bucle cuentan dentro de estos por ejemplo for(let i = 0; i<10;i++)

Este scope solo funciona con let o const, este scope permite su alcance dentro del bloque en el que se instancia ya sea un bucle, un if o un bloque forzado (las llaves puestas solas {} con el único propósito de generar un nuevo scope)
P.D. las variables declaradas en los parámetros de una función o bucle cuentan dentro de estos por ejemplo for(let i = 0; i<10;i++)

Mis apuntes (4) 😃

// 🧱 Block scope

//Block scope con var, let y const
const fruits = () => {
  if (true) {
    var fruit1 = "apple"; // 🏭 Se asgina al scope de la funcion
    let fruit2 = "banana"; // 🧱 Se asigna al scope del bloque
    const fruit3 = "kiwi"; // 🧱 Se asigna al scope del bloque

    console.log(fruit2); //🧱
    console.log(fruit3); //🧱
  }
  console.log(fruit1); // 🏭
};

fruits();

// Con let respeto el 🧱 block scope
let x = 1;
{
  let x = 2;
  console.log(x);
}
console.log(x);

// Con var no se respeta el bloque (🌎 global scope)
var x = 1;
{
  var x = 2;
  console.log(x);
}
console.log(x);

// Es mas amigable usar let en vez de var en un ➿ bucle
//let
const anotherFunction = () => {
  for (let i = 0; i < 10; i++) {
    setTimeout(() => {
      console.log(i); //Resultado 0-9
    }, 1000);
  }
};

anotherFunction();

//var
const anotherFunction = () => {
  for (let i = 0; i < 10; i++) {
    setTimeout(() => {
      console.log(i); //Resultado 10 x 10 veces
    }, 1000);
  }
};

anotherFunction();

Creo yo que este código lo explica muy bien c:

//Block Scope con var 

const fruits = function () {
  if (true) {
    var fruit1 = 'Apple'
    var fruit2 = 'Banana'
    var fruit3 = 'Kiwii'
  }
  console.log(fruit1)
  console.log(fruit2)
  console.log(fruit3)
}

freuits() // Va a devolver los valores de las 3 variables

// Block Scope con let y const

const fruits2 = function () {
  if (true) {
    var fruit1 = 'Apple'
    let fruit2 = 'Banana'
    const fruit3 = 'Kiwii'
  }
  console.log(fruit1)
  console.log(fruit2)
  console.log(fruit3)
}

//Solo devolvera el valor de la variable con var,
//ya que esta solo ocupa un scope de funcion y las demas de bloque```
const frutas =()=>{
  if (true){
    //las variables de tipo var tienen un function scope dentro de un bloque
    var fruta1 ='apple';
    //las variables let y const tienen un block scope
    let fruta2 ='banana';
    const fruta3 ='kiwi';
    console.log(`${fruta2} ${fruta3}`);
  }
console.log(`${fruta1} `);
}
  
frutas();
//let
let x =1;//<= Esta variable existe en el global, pero no en el block
{
  let x =2;//<= Esta variable solo existe en el block scope, por eso no presenta problema
  console.log(x);//<=Imprimimos la  variable dentro del bloque
}
console.log(x);//<=Imprimimos la varible golobal.
//var
var x =1;//<= Esta variable existe en el global
{
  var x =2;//<= Esta variable es la misma del global y se reescribe en esta linea
  console.log(x);//<=Imprimimos la  variable dentro del bloque, que es la misma del global
}
console.log(x);//<=Imprimimos la varible golobal.(

const funcionIteracion=()=>{
  //La variable se va a sobreescribir hasta tomar el valor de 10
  for (var i=0;i<10;i++){
    setTimeout(()=>{//Esto se ejecuta  1SEGUNDO DESPUES de acabar el for
      console.log(i);
    },1000)
  }
}
funcionIteracion();

const funcionIteracion=()=>{
  //La variable recuerda el valor que tenia 
  for (let i=0;i<10;i++){
    setTimeout(()=>{//Esto se ejecuta  1SEGUNDO DESPUES de cada iteracion
      console.log(i);
    },1000)
  }
}
funcionIteracion();

Entonces creo que la mejor forma de trabajar con el ciclo for es usando let, para evitar problemas…

A lo que estoy entendiendo sea donde sea que se declare la palabra reservada “var” es como si fuera una variable global

Lo que vamos a ver es cada uno de los pasos que esta intentando desde 0 … 9 y de esta forma nosotros estamos entendiendo la forma de llevar el Scope Local en formato de bloque a todos nuestros bloques de código.

Por aca dejo mi código:

if (true) {
  var fruit1 = "apple";
  let fruit2 = "banana";
  const fruit3 = "kiwi";
  console.log(fruit2);
  console.log(fruit3);
}
console.log(fruit1);

let x = 1;
{
  let x = 2;
  console.log("let", x);
}
console.log("let", x);

var y = 1;
{
  var y = 2;
  console.log("var", y);
}
console.log("var", y);

const func1 = () => {
  // Que no uses VAR miserable sabandija!!!!!!!
  for (var index = 0; index < 10; index++) {
    setTimeout(() => {
      console.log(index);
    }, 1000)
  }
  for (let index = 0; index < 10; index++) {
    setTimeout(() => {
      console.log(index);
    }, 1000)
  }
}
func1();

comparto codigo de la clase:


// Block Scope
const fruit = () => {
    if (true) {
        var  fruit1 = 'apple';
        let  fruit2 = 'banana';
        const  fruit3 = 'orange';
   }
    console.log(fruit1);
    console.log(fruit2); // no se puede acceder porque esta fuera del bloque
    console.log(fruit3); // no se puede acceder porque esta fuera del bloque
}
fruit();

// USO LET
let x=1;
{
    let x=2;
    console.log(x);  // se nuestra "2" se define en el bloque
}
console.log(x); //nuestra "1" primera definicion

// USO VAR
var x=1;
{
    var x=2;
    console.log(x);  // se nuestra "2" por ultima definicion
}
console.log(x); // se nuestra "2" por ultima definicion

// funcion que trabajo en loop basado asignacion de var y  loop

// uso var
const anotherFunction = () => {
    for (var i = 0; i < 10; i++) {
        setTimeout(() => {
            console.log (i);
        }, 1000)
    }
};
anotherFunction(); //ejeucuta 10 veces el valor de 10 porq es el ultimo valor asignado

// uso let
const anotherFunction = () => {
    for (let i = 0; i < 10; i++) {
        setTimeout(() => {
            console.log (i);
        }, 1000)
    }
};
anotherFunction();  //cada uno de los pasos que se incrementa

En el último ejemplo, algo que no entendía bien y que se que yo no puedo ser el único que se saco de onda con esto es que el “setTimeout” se manda a llamar 10 veces mucho muy rápido en cada iteración, osea, se ejecuta 1 vez y por cuestión del eventLoop, se queda la instrucción de que en 1000 milisegundos se escriba el log en consola del valor que tiene " i ", entonces ya llegados los 1000 milisegundos del primer setTimeout, el valor de " i " llego hasta 10, porque se reasigno en cada ciclo del for hasta llegar a 10, es por eso que imprime puros 10, porque al accesar a la sección de la memoria donde se guarda el valor " i " tiene 10.

Caso contrario con let, porque se van guardando los valores en cada iteración, se puede decir que llegamos a tener 10 veces la variable " i " por cada ciclo del for, que es lo que normalmente nosotros esperamos, que en cada ciclo haga algo nuestra función con el valor actual de los datos.

Con var solo se muestra el 10 porque se va re-asignando con cada aumento del ciclo for, recuerden que var puede ser reasignada pero let no. Es por esto que establecer la variable como let es la solución.

La declaración de una variable como VAR, obtiene el scope de la función, no del bloque, por ésta razón podemos acceder a ella fuera del bloque de código.

Importante cada vez que se pueda realizar la declaracion de nuestras variables al inicio del documento con let, de esta manera no podremos redeclararla dentro del programa pero si utilizarla detro de los scopes locales.

Todo el código que este dentro de llaves se le denomina bloque.

Cuando declaramos una variable let o const dentro de un bloque, el alcance o scope que tendrá será sólo dentro de ese bloque.

El hoisting de la variables definidas con var, muy interesante como se comporta el lenguaje. En el curso profesional de js tambien lo vemos un poco por encima

Muy útil el **let** para el *for*! Era una duda que me había quedado del curso de fundamentos de JavaScript cuando el profesor hizo ese cambio.

Te confundiste un poco al final explicando que banana es lo primero que se imprime que es el console del bloque pero a ti se te perdona todo Oscar, eres un Crack !

Block Scope: Un bloque de código es un pedazo de estructura de código. Dentro del bloque se pueden crear variables ( var , let o const ), sin embargo éstas variables solamente habitan en el bloque de código y pueden acceder a los elementos el ámbito en que se encuentran.
·
·
Con asignación de var, ámbito de función.
Con asignación de let & const, ámbito de bloque.

Para los que no les quedo claro por que imprime //0 1 2 3 4 5 6 7 8 9, como explica el profesor aqui, tenemos tres entornos léxicos, el entorno léxico anotherFunction y el entorno léxico for y entorno léxico setTimeout, lo que esta pasando es que en la primera iteracion en el entorno léxico del setTimeout, estamos imprimiendo i, pero como i no existe en ese entorno léxico pasaríamos a buscarlo en el siguiente entorno léxico el cual seria el del for, entonces iteracion i = 0, entonces actualiza el valor de i para el entorno léxico del setTimeout (i = 0), luego se ejecuta la segunda iteracion, vemos que en el entorno lexico del setTimeout se vuelve a imprimir i, pero para este NUEVO(es un nueva función) entorno léxico setTimeout y no existe, por tanto se vuelve a subir un nivel y vemos que en el entorno léxico del for esta vez i = 1, entonces recuperamos ese valor para el entorno lexico de setTimeout i = 1, y así sucesivamente //0 1 2 3 4 5 6 7 8 9
const anotherFunction = () => {
for (let i = 0; i < 10; i++) {
setTimeout(() => {
console.log(i)
}, 1000)
}
}
anotherFunction()

Luego de darle al coco un rato, esta fue la manera en que pude organizar las cosas en mi mente:
//

function printNumbers() {
	for (var i = 0; i < 5; i++) {
		setTimeout(
      function printer() {
	      console.log(i);
	    } ,100 * i ); }
}

printNumbers();

//ocurre el primer ciclo

function printNumbers() {
	var i
	for (i = 0; i < 5; i++) {
		i = 0;    //esto se sale para arriba, afuera del for
		setTimeout(
      function printer() {
	      console.log(i);
	    } ,100 * i ); 
	}
}

/*se ejecuta con 0 pero la condicion del ciclo for la ejecuta el navegador y la pone en 
el callstack, mientras setTimeout pone su funcion de console.log en el callback queue po
ende las ordenes de console.log estan lista para ejecutarse solo despues que lo que esta
en el callstack que es la condicion for con los valore de i*/

//Todo es culpa del hoisting, porque VAR tiene scope de Funcion y let scope de Bloque
//Cuando el codigo itera va a pasar lo siguiente 
//se ejecuta cada bloque for 

var i = 0
/*la variable i que se salio por el hoisting, era undefined, pero luego en el ciclo
for fue asiganada como 0 */
//mientras, por el otro lado, se agenda un console.log en el callback queue
for (i = 0; i < 5; i++) {
		setTimeout( 
      function printer() {
	      console.log(i);
	    } ,100 * i ); 
	}
/*como cada vez que el ciclo corre, var i suma 1, y se sale fuera del for, al scope de 
la funcion */
// el for se ejecuto 5 veces, pero cada que se ejecuto, el valor de 'var i' se reasignó
function printNumbers() {

var i = 0
for (i = 0; i < 5; i++) {
		setTimeout( 
      function printer() {
	      console.log(i);
	    } ,100 * i ); 
	}

var i = 1
for (i = 0; i < 5; i++) {
		setTimeout( 
      function printer() {
	      console.log(i);
	    } ,100 * i ); 
	}

var i = 2
for (i = 0; i < 5; i++) {
		setTimeout( 
      function printer() {
	      console.log(i);
	    } ,100 * i ); 
	}

var i = 3
for (i = 0; i < 5; i++) {
		setTimeout( 
      function printer() {
	      console.log(i);
	    } ,100 * i ); 
	}

var i = 4
for (i = 0; i < 5; i++) {
		setTimeout( 
      function printer() {
	      console.log(i);
	    } ,100 * i ); 
	}

//como var i se salio cada vez, al valor final de i va a ser var i = 4
/*El ciclo for se acaba, el callstack se desocupa, entra en accion el callback queue,
con 10 ordenes pendientes de console.log, cuando estas se imprimen, encontraran cada vez
esto: */
//ultimo valor del for es 4
function printNumbers() {
	var i = 4;
	/*for (var i = 0; i < 5; i++)*/ {
		setTimeout(
      function printer() {
	      console.log(i);
	    } ,100 * i ); }
}
/*porque var i termina siendo 4, ya que al escapar al scope de funcion y no estar en el 
y no estar en el scope de bloque del ciclo, esta, se reasigno cada vez. Quedamos con
un unico binding de 'var i' que vale '4'*/

//con let pasa diferente:
//cada valor de let i, itero y se quedo independiente dentro del scope de bloque.
/*El ciclo for se acaba, el callstack se desocupa, entra en accion el callback queue,
con 10 ordenes pendientes de console.log, cuando estas se imprimen, encontraran cada vez
esto: */

function printNumbers() {

for (i = 0; i < 5; i++) {
	let i = 0
		setTimeout( 
      function printer() {
	      console.log(i);
	    } ,100 * i ); 
	}

for (i = 0; i < 5; i++) {
		let i = 1
		setTimeout( 
      function printer() {
	      console.log(i);
	    } ,100 * i ); 
	}

for (i = 0; i < 5; i++) {
		let i = 2
		setTimeout( 
      function printer() {
	      console.log(i);
	    } ,100 * i ); 
	}

for (i = 0; i < 5; i++) {
		let i = 3
		setTimeout( 
      function printer() {
	      console.log(i);
	    } ,100 * i ); 
	}

for (i = 0; i < 5; i++) {
		let i = 4
		setTimeout( 
      function printer() {
	      console.log(i);
	    } ,100 * i ); 
	}
//todo esto pasa por dentras
--

lamentablemente sigue llamando ‘asignacion’ a lo que es ‘declaracion’, pero no hay que confundir ese concepto.

Cuando declaramos con let y const el scope de la variable es el bloque (no la función), en este caso sólo existen dentro del if.

Si desean las notas que voy a ir tomando de los cursos las voy a publicar en un repositorio, se las comparto estas son las de este curso:

https://github.com/patogalarzar/code-notes/tree/main/Closures-Scope

Sabemos que al tener elementos dentro de un bloque de codigo estos podrian funcionar como un scope global, pero si tenemos un BLOQUE dentro de una funcion, esto sera un caso especial, todo depende de la palabra clave que usemos. Si usamos LET o CONST solo funcionaran en el bloque de codigo que seran declarados PERO var si podra ser utilizada y manipulada por LA FUNCION.

let x = 1;
{ 
	let x = 2;
	console.log(x); --> 2
}
console.log(x) --> 1

Para los que como yo son nuevos en JavaScript y no entendieron muy bien la sintaxis del bucle for del ejemplo del profesor:

The for loop has the following syntax:

for (statement 1; statement 2; statement 3) {

}

Statement 1 is executed (one time) before the execution of the code block.

Statement 2 defines the condition for executing the code block.

Statement 3 is executed (every time) after the code block has been executed.

Me encanta como explica las cosas el profe pero me sangran los oidos con su inglés, Platzi patrocinale tu escuela de inglés :B

// definimos un function scope
const fruits = () =>{
    // definimos un block scope
    if(true){
        var fruit1 = 'apple'
        const fruit2 = 'banana'
        let fruit3 = 'kiwi'
        console.log(fruit2)
        console.log(fruit3)
    }
    console.log(fruit1)
}
fruits()


let x = 1
// definimos un blockscope con let, la reasignacion solo vive
// dentro del block scope
{
    let x = 2
    console.log(x)
}
console.log(x) 

// definimos un blockscope con var, la reasignacion es global
var x = 1
{
    var x = 2
    console.log(x)
}
console.log(x)

// creamos un function scope
const hello = () =>{
    // creamos un blockscope dentro de un function scope
    // si no definimos i, se reasigna como global
    for(i = 0; i < 10; i++){
        setTimeout(()=>{
            console.log(i)
        }, 100)
    }
}
hello()

// mismo ejercicio pero asignando i con 'let' para que solo 
// tenga block scope y se ejecute correctamente
const bye = () =>{
    for(let i = 0; i < 10; i++){
        setTimeout(()=>{
            console.log(i)
        }, 100)
    }
}
bye()
  • scope local en bloque y scope local en funciones. var es una asignación de función y let y const son asignaciones de bloque.

Resumen de la clase

const fruits = () => {

    // Var es un ambito de funcion
    // let y const SOLAMENTE pueden accederse a ellos dentro del bloque IF
    if(true) {
        var fruits1 = 'apple';
        let fruits2 = 'banana';
        const fruits3 = 'kiwi';

        console.log(fruits2);
        console.log(fruits3);
    }

    console.log(fruits1);
}
fruits();

// Con LET Nns mustra primero el valor del bloque
// Con VAR reasigna ambos valores
let x = 1;
{
    let x = 2;
    console.log(x);
}
console.log(x);

// si usamos VAR este nos reasigna el y queda en 10
// si usamos LET declara un valor unico y de manera correcta
const anotherFunction = () => {
    for(let i = 0; i < 10; i++) {
        setTimeout(() => {
           console.log(i); 
        }, 1000);
    }
}
anotherFunction()

VAR su alcance es dentro de toda una funcion, vive en toda la funcion.
LET y CONST su alcance es solo dentro de las llaves donde fueron declaradas, solo viven dentro de sel bloque de llaves!

Una pequeña explicación para los que aún no logran comprender var, let. y const, así como el ámbito de función y de bloque:

  1. Evitar el uso de var en la medida de lo posible, es decir, nunca utilizarlo a no ser que sea de vida o muerte, o sea nunca :p ¿Porqué? Es inseguro y muy alterable. En pocas palabras, utiliza var si quieres ser hackeable 😄
  2. let y const funcionan sobre el ámbito local estricto, es decir que sólo funcionará en el bloque en donde se declaró, así como los bloques internos. A continuación se explica en modo de ejemplo:
const miFuncion = () => {
  let variable_funcion = "Hola, existo en toda la función y me pueden modificar, pero no me pueden redeclarar";
  const constante_funcion = "Hola, existo en toda la función y no me pueden modificar, ni mucho menos redeclarar";
  if (true) { // Este es el primer bloque interno (nivel 1)...
    let variable_funcion = "Esto marcará error porque no me puedes redeclarar";
    variable_funcion = "Pero SÍ me puedes reasignar valor";
    const constante_funcion = "Error: No puedes redeclararme porque soy una constante";
    constante_funcion = "También es error! Porque tampoco puedes reasignarme valor";
    if (true) { // Este es el segundo bloque interno (nivel 2)
      var variablehackeablenivel2 = "Hola, estoy hasta el bloque interno nivel 2 pero aún así mi padre, o sea toda la función, puede verme... y soy feliz de ser hackeable :D"
      let variablenivel2 = "Hola, soy un variable que solo estará disponible dentro de este if, porque soy let y trabajo sobre un ámbito local estricto... y no me gusta ser hackeable :D"
      variable_funcion = "Correcto! Aquí también puedes reasignarme valor porque este bloque es más interior al bloque en donde fui declarada.";
      // Y las constantes ni se digan, ni dentro ni fuera pueden ser, ni redeclaradas ni reasignadas, pero sí puedo accesar a ellas siempre y cuando hayan sido declaradas en este mismo bloque o en bloques PADRE a este.
      console.log(constante_funcion); // Por lo que aquí me mostaría en pantalla Hola, existo en toda la función y soy inmutable.
    };
  };
  console.log(variablenivel2); // ERROR: Porque esa variable fue declarada 2 niveles dentro con let, y yo no puedo verla aunque soy padre de ese bloque... porque let trabaja sobre el ámbito local estricto.
  console.log(variablehackeablenivel2); // FELICIDADES: Accediste a una variable que declaraste 2 niveles adentro y fuiste hackeado, ahora tu cuenta bancaria está en ceros :D
};
miFuncion(); // Les dará unos cuantos errorsillos intencionales por las cuestiones que están explicadas dentro del código de la función.
// Justo aquí ya estamos fuera de miFunción por lo que no puedo acceder ni a variable_funcion, ni a constante_funcion, y mucho menos a variablenivel2, porque todas ellas fueron declaradas en el Scope de la función.

Espero que esta pequeña explicación les sirva a comprender un poco mejor lo que significa el scope de función y la forma como trabajan let, const y var.

NOTA: NO UTILICEN VAR. Happy coding!!!

Gracias por la explicación, semejante lío el que se arma con el loop usando:

var

en lugar de :

let

Y lo bueno es que VSC me lo dice de antemano

estuvo muy bien explicado qué es un bloque en JavaScript y su relación con el Scope

excelente clase!

Var === Caos.

Este comentario son tres ejemplos de la misma función del recorrido del bucle for pero cada uno se declara con var, otro con let y otro const para observar su funcionamiento.

<const myfunction = () => {
    for (var i = 0; i<10; i++){
        setTimeout(() => {
            console.log(i);
        })
    }
}

myfunction(); /* SALIDA DEL PROGRAMA
10
10
10
10
10
10
10
10
10
10 */

const myfunction2 = () => {
    for (let i = 0; i<10; i++){
        setTimeout(() => {
            console.log(i);
        })
    }
}

myfunction2();/* SALIDA DEL PROGRAMA
0
1
2
3
4
5
6
7
8
9 */

const myfunction3 = () => {
    for (const i = 0; i<10; i++){
        setTimeout(() => {
            console.log(i);
        })
    }
}

myfunction3();/* SALIDA DEL PROGRAMA
TypeError: Assignment to constant variable.
*/> 

conclusión de todo el curso xd

No utilicen el VAR si no el LET Y CONST ❤️

Las variables var pueden ser modificadas y re-declaradas dentro de su ámbito; las variables let pueden ser modificadas, pero no re-declaradas; las variables const no pueden ser modificadas ni re-declaradas. Todas ellas se elevan a la parte superior de su ámbito.

Es muy importante dar a las variables nombres que indiquen el valor que contienen. De esta forma se auto documenta y la App es más clara para otra Persona que empiece a actualizarla. No es recomendable usar x, y, etc. Además una variable sólo debe contener un valor en la App, no reusarla para diferentes valores. Son buenas prácticas

¿Qué significa cuando el profesor dice un typo?

Typo is short for typographical error—a mistake made when typing something.

const anotherFunction=()=>{
    let n =0
    for(var i = 0; i<10 ; i++){
        setTimeout(()=>{ console.log('i :' +i); },1000);
        setTimeout(()=>{ console.log('n :' +n++); },0.01);   
        console.log("dimos una vuelta mas al for");         
    }
}

anotherFunction();
// 10 dimos una vuelta mas al for   // se ejeta las 10 veces de primeras
// undefined
//  n :0
//  n :1
//  n :2
//  n :3
//  n :4
//  n :5
//  n :6
//  n :7
//  n :8
//  n :9
// 10 i :10  // se ejeta las 10 veces de ultimas

Lo que entiendo sobre lo que le sucedió a var en el último ejercicio es que presenta el comportamiento de reasignación.
Si recorremos la lógica del bloque de codigo vemos que inicia en 0 y luego del primer ciclo se le suma 1
terminando en el ultimo ciclo como 9 + 1 = 10;