La traducción de scope es alcance. Entonces el scope es el alcance que tiene cada variable en nuestro código.
Podemos verlo como un bloque que contiene otros bloques. El bloque superior (scope global) contiene y puede ser accedida desde todos los otros bloques hijo.
Un bloque puede ser cualquier cosa que esté entre llaves curvas.
{}
Literalmente cualquier cosa. Incluso podemos poner un par de llaves curvas que no tiene ninguna funcionalidad y ya sería un bloque. Las funciones, los condicionales (IF, ELSE ...) y los bucles (WHILE, FOR, DO ...) crean bloques. Cuando veas llaves curvas, eso es un bloque.
// Esto es un bloque con una variable dentro: { var ejemploVariable = "texto texto texto"; console.log(ejemploVariable; } // Esto es otro bloque que es un condicional if (condición) { var otroEjemploVariable = "texto2 texto2 texto2"; console.log(otroEjemploVariable); }
Scope local - Variables locales
Una función contiene instrucciones que no van a ser ejecutas hasta que hagamos una llamada después a esa función. Una función por si sola no hace nada. En el momento de llamarla se crea una bloque opaco. Dentro de ese bloque están tanto las variables, como otras funciones que hayamos declarado previamente. Pero ese bloque es opaco. Si desde fuera de la función intentamos acceder directamente a una variable no vamos a poder, dará error undefined (sin definir), por que para la aplicación, esa variable solo existe dentro de esa función.
Ejemplo:
function miFuncion() { const unaVariable = "Un poco de texto"; return unaVariable; } // Una función por si sola no hace nada. Siempre hay que llamarla: miFuncion(); //Si intentamos acceder a la variable unaVariable directamente nos saldrá un error. // Tanto intentando hacer un log como llamándola directamente. // Resultado: Uncaught ReferenceError: unaVariable is not defined. console.log(unaVariable); unaVariable;
Scope global - Variables globales
¿Recuerdas la metáfora de los bloques? Que cada elemento que tenga llaves curvas (funciones, condicionales, etc) es un bloque. Pues el bloque 0 es el scope global. Cuando digo bloque 0 me refiero a la base del programa.
Ejemplo:
// Scope Global. No esta dentro de ninguna función. const unaVariable = "Más texto"; function miFuncion() { const modificoVariable = unaVariable + " y lo puedo editar por que la otra variable (unaVariable) es global y esta función es hijo"; return modificoVariable; } miFuncion();
Podemos acceder a cualquier variable siempre que este declarada antes de la función, a un nivel superior. Por ejemplo en una función tiene una variable y dentro tiene otra función que puede hacer uso de esa variable.
function miFuncion() { const unaVariable = "Un poco de texto"; function otraFuncion() { const modificoVariable = unaVariable + " mismo ejemplo anterior pero con funciones anidadas"; // console.log(unaVariable); // console.log(modificoVariable); return modificoVariable ; } return otraFuncion(); } // Una función por si sola no hace nada. Siempre hay que llamarla: miFuncion();
Variables JavaScript
Podemos definir variables con 3 palabras clave:
- const
- let
- var
Tienen 2 diferencias principales:
Diferencia 1 - Modificación
La variable const NO se puede modificar una vez declarada. Por ello se le llama variable inmutable. Se suele usar este tipo de variable para datos que no queremos nunca a lo largo de todo el programa.
Ejemplo:
const noModificable = "Si la modificas te da error."; noModificable = "texto texto texto"; // Al ejecutar da el error: // Uncaught TypeError: Assignment to constant variable.
Por el otro lado, las variables let y var SÍ se pueden volver a modificar una vez declaradas. Justo al contrario que const. Por ello se les llama variables mutables. Se suele usar let antes que var, la razón es por la siguiente diferencia.
Ejemplo:
let noModificable = "La puedes modificar sin problema al igual que var"; console.log(noModificable); noModificable = "texto texto texto"; console.log(noModificable);
Diferencia 2 - Alcance y visibilidad
La otra diferencia es el scope (alcance).
En el scope global tanto una variable var, let o const van a poder ser accesibles. No hay diferencia de visibilidad.
A nivel de scope local es cuando hay diferencias.
Let y const
Las variables let y const son block scoped.
Las variables let y const tienen el scope (alcance) solo en el bloque que se declaran. Eso significa que solo van a "vivir" en ese bloque. Es igual que hemos visto anteriormente. Cualquier bloque, tanto unas simples llaves curvas, como una función, como un condicional o un bucle.
Ejemplo:
for (let i = 0; i < 9; i++) { console.log(i) } // La variable i no va existir fuera del bloque FOR // Va a dar error: Uncaught ReferenceError: i is not defined console.log("Se puede acceder desde fuera del bloque: " + i);
var
La variable var es function scoped. La variable var tiene el scope a un nivel más alto. Esto significa que una variable declarada con var no se va a quedar dentro de las llaves curvas. Excepto si esas llaves son las de una función. Es el único caso en el cual no va a poder ascender a global.
Por decirlo así, rompe el scope local y asciende a global excepto si el bloque es función.
Ejemplo en el que si va a ascender de su bloque a global. Unas llaves simples, bucles o condicionales.
{ // primer bloque var a=10; console.log(a); } { // segundo bloque // aunque sean 2 bloques diferentes podemos modificar y utilizar la variable var a++; console.log(a); }
Mismo caso pero con un bucle FOR:
for (var i = 0; i < 9; i++) { console.log(i) } // La variable i va a tener el valor igual al último momento del bucle. // Y vamos a poder utilizarla fuera del bloque donde se declaró console.log("Se puede acceder desde fuera del bloque: " + i);
Ejemplo de la excepción al estar en una función:
function miFuncion() { var unaVariable = "texto texto texto"; console.log(unaVariable); } miFuncion(); console.log(unaVariable);
Pequeña diferencia entre var y let
La diferencia esta en que var se puede volver a inicializar y let no.
Ejemplo:
var ejemplo = "primero"; var ejemplo = "segundo"; // el resultado va a ser el segundo. console.log(ejemplo); let ejemplo = "primero"; let ejemplo = "segundo"; // Va a dar error: // Uncaught SyntaxError: Identifier 'ejemplo' has already been declared console.log(ejemplo);