El alcance o scope de las variables - Diferencias var y let - Curso de JavaScript de cero a máster - Capítulo 28

JavaScript es un lenguaje algo peculiar a la hora de definir los alcances de las variables, y no lo digo en el mal sentido.

Vamos a ver en este capítulo como funciona el ámbito de las variables, también conocido como alcance, visibilidad o scope en inglés. Un tema fundamental para trabajar correctamente con variables.

Ámbito global de JavaScript

El ámbito global se refiere al alcance de una variable sobre toda una hoja .js.

Cuando declaramos una variable fuera de un elemento como una función, un condicional o un bucle, esta toma un status (estado) global y es visible dentro de estas estructuras que acabo de mencionar.

Hagamos una prueba tanto con var como con let, ya que funcionan de forma diferente.

Código JavaScript

var variable1 = "Alcanzada la variable con VAR.";
let variable2 = "Alcanzada la variable con LET.";

function alcances(){
	console.log(variable1 + "\n" + variable2);
}

alcances();

Resultado en la consola

Alcanzada la variable con VAR.
Alcanzada la variable con LET.

En este caso, las dos variables son alcanzadas dentro de la función sin ningún problema. Pero ¿Qué pasa si declaro otras variables con el mismo nombre dentro de la misma hoja .js?

Código JavaScript

var variable1 = "Alcanzada la variable con VAR.";
let variable2 = "Alcanzada la variable con LET.";

var variable1 = "Alcanzada la variable con VAR.";
let variable2 = "Alcanzada la variable con LET.";


function alcances(){
	console.log(variable1 + "\n" + variable2);
}

alcances();

Resultado en la consola

 Uncaught SyntaxError: Identifier 'variable2' has already been declared - line 5

Dice que el identificador de la variable2 ya está declarado. Esperábamos que ocurriera un error, pero, ¿porqué el error se refiere solo a variable2? ¿Qué pasa con la variable1 declarada con var?

Algo de esto expliqué en el capítulo 5. Dije lo siguiente, por si no lo recuerdas:

Con var podemos redeclarar una variable tantas veces como queramos utilizando la palabra reservada delante del identificador.

Por eso la consola no da ningún error. Está permitido, en cambio, con let no. Es uno de los motivos de tener dos palabras para declarar variables.

Quitamos la redeclaración de variable2 y funciona sin problemas:

Código JavaScript

var variable1 = "Alcanzada la variable con VAR.";
let variable2 = "Alcanzada la variable con LET.";

var variable1 = "Redeclaración con VAR.";

function alcances(){
	console.log(variable1 + "\n" + variable2);
}

alcances();

Resultado en la consola

Redeclaración con VAR.
Alcanzada la variable con LET.

Ámbito local y de bloque de las variables

Gracias a la palabra let podemos crear ámbitos locales de las variables y limitar su acceso a bloques como un condicional, un bucle, una función...

En el siguiente ejemplo, tienes dos variables de alcance local al encontrase declaradas dentro de la función.

Código JavaScript

function alcances(){
	let variable1 = "Variable1 dentro de la función.";
	var variable2 = "Variable2 dentro de la función.";
	console.log(variable1 + "\n" + variable2);
}

alcances();

Resultado en la consola

Variable1 dentro de la función.
Variable2 dentro de la función.

Estas variables no se pueden acceder desde fuera, al estar declaradas dentro de la función, se limita su acceso a la propia función. Probémoslo.

Código JavaScript

function alcances(){
	let variable1 = "Variable1 dentro de la función";
	var variable2 = "Variable2 dentro de la función";
	console.log(variable1 + "\n" + variable2);
}

alcances();

console.log(variable1);
console.log("\n");
console.log(variable2);

Resultado en la consola

 Uncaught ReferenceError: variable1 is not defined at line 9

Me devuelve el error de que variable1 no está definida. Lo mismo pasaría con variable2 si estuviera antes de variable1, el error no aparece, pero igualmente no la alcanza. Puedes hacer la prueba.

Pasemos a un ejemplo con el alcance de bloque, también local. Vamos a ver en este caso, un condicional if con una variable declarada dentro del bloque de código if, la variable suma.

Código JavaScript

let numero1 = 1500;
let numero2 = 1200;
if (numero1 > 1000){
	var suma = numero1 + numero2;
}

console.log("El valor total de la suma es: " + suma);

Resultado en la consola

Podemos pensar que al igual que ocurre con las funciones, no podremos acceder a esta variable llamada suma por el simple hecho de no estar creada fuera de un bloque. No obstante, se puede acceder sin problemas, el alcance está funcionando como global aunque debería ser local.

El valor total de la suma es: 2700

Esto ocurre porque estoy declarando la variable suma con var. Uno de los motivos de crear let es este, ya que let funciona diferente, tiene lo que se conoce como alcance de bloque (block scope en inglés).

Código JavaScript

let numero1 = 1500;
let numero2 = 1200;
if (numero1 > 1000){
	let suma = numero1 + numero2;
}

console.log("El valor total de la suma es: " + suma);

Resultado en la consola

Curiosamente, con let, me aparece la variable suma como no definida. Por lo tanto, aquí tienes otra diferencia entre var y let.

 Uncaught ReferenceError: suma is not defined at line 7.

Pasemos a ver algún ejemplo con bucles.

Código JavaScript

for(i=1;i<=10;i++){
	console.log("El valor del bucle es: " + i);
}

Al escribir la variable i la primera vez en el bucle, la estamos declarando de la misma forma que haríamos con var.

Código JavaScript

for(var i=1;i<=10;i++){
	console.log("El valor del bucle es: " + i);
}

Esto quiere decir que si dejamos la variable del bucle con var o sin nada más que su nombre, no se utilizará este alcance de bloque y la variable será accesible a nivel global.

Código JavaScript

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

console.log("El valor del bucle al finalizar es: " + i);

Resultado en la consola

El valor del bucle al finalizar es: 11

En cambio, si hacemos esto con let, la variable toma alcance de bloque y no se puede acceder a ella desde fuera del bucle:

Código JavaScript

for(let i=1;i<=10;i++){
}

console.log("El valor del bucle al finalizar es: " + i);

Resultado en la consola

 Uncaught ReferenceError: i is not defined at line 4

Suficientes conceptos sobre el alcance para esta parte del curso. El siguiente capítulo será el segundo proyecto del curso, una calculadora.


Ejercicios de JavaScript

  1. ¿Qué valor devuelve la consola? Intenta resolverlo antes de ejecutarlo.
  2. Código JavaScript

    let variable1 = "Fuera del bloque.";
    if (true) {
    	let variable1 = "Dentro del bloque.";
    	console.log(variable1);
    }
    console.log(variable1);
    
  3. ¿Qué valor devuelve la consola? Intenta resolverlo antes de ejecutarlo.
  4. Código JavaScript

    var variable1 = "Fuera del bloque.";
    if (true) {
    	var variable1 = "Dentro del bloque.";
    	console.log(variable1);
    }
    console.log(variable1);

La solución la encontrarás aquí: Haz click aquí.


Capítulos


    Suscríbete a mi canal de YouTube para apoyarme

    Si te ha gustado este curso y crees que el trabajo merece la pena, te agradeceré eternamente que te suscribas a mi canal de YouTube para apoyarme y que pueda seguir haciendo cursos gratuitos.

    Además, si te encanta la programación, tienes un montón más de cursos gratuitos para ver.

    No solo eso, podrás participar enviándome comentarios con tus sugerencias para temas específicos o cursos completos o incluso las dudas que tengas y las intentaré ir resolviendo en los cursos que estén todavía abiertos.


    Comentarios

    Si te quedan dudas sobre el temario, sobre JavaScript, o cualquier otra cosa relacionada o simplemente quieres agradecer, aquí tienes tu sitio para dejar tu granito de arena. Gracias por tus comentarios y por darle vida a este sitio web.