En este artículo explico qué son los scopes y las variables let, const y var y cómo pueden ser una ventaja o un problema. En lineas generales las palabras let
, const
y var
sirven para describir su scope y comportamiento. Así que lo primero sería entender qué es esto del scope.
Antes de nada, los scopes
Hay 3 tipos de scopes, que dicho de una forma más natural, vendría a ser el lugar en el que viven y son accesibles las variables. Existe el global scope, el local scope y el block scope. Tanto let
como const
forman parte de este último.
El global scope es el que se puede escribir y leer en cualquier lugar, y viviría en el objeto window
. Por ejemplo:
(function test(){
name = "Barb"; // Ojo, no uso la palabra var
})();
console.log(window.name); // Barb
Imagina lo peligroso que es esto, tienes variables que se pueden sobreescribir y no sabes ni por dónde te van a venir los palos.
El local scope contendría las variables dentro de una función, y para usarlo se escribiría var
delante.
(function test(){
var name = "Barb";
})();
console.log(window.name); // undefined (name sólo existe dentro de test()
El block scope vendría a ser el comportamiento que habitualmente esperarías. Es parecido al local scope pero ligeramente más restrictivo ya que restringe a cualquier bloque delimitado por {}
, no sólo funciones.
(function test(){
let letters = ["B", "i", "g", "g", "i", "e"];
let name = "";
for(let i = 0; i < letters.length; i++){
// Dentro de este bloque tengo acceso tanto a name como a i
name += letters[i];
}
// En este bloque ya no tengo acceso a i, sólo a letters y name.
console.log(letters); // ["B", "i", "g", "g", "i", "e"]
console.log(name); // "Biggie"
console.log(i); // Uncaught ReferenceError: i is not defined
})();
¿Qué pasaría si en este for
hubiéramos definido la i
del bucle con var
en lugar de let
? Pues que el último console.log
no fallaría, mantendríamos acceso a él desde ahí (y podríamos modificarlo). ¿Y si hubiéramos omitido usar var
siquiera? El desastre: tendríamos acceso a esa i en cualquier lugar del código.
Cuando usar const
Usamos const cuando el valor de la variable no se puede reasignar. Por ejemplo si decimos que const name = "Poppy";
, desde ese momento no podremos volver a definirlo, ni volviendo a usar la palabra clave const
ni sin ella, de manera que name = "Barb"
; daría un error como este:
Uncaught TypeError: Assignment to constant variable.
Esto no significa que sea inmutable. La inmutabilidad es otro concepto interesante pero que no explicaré de momento, quiero mantener esto sencillo. El valor podría mutar en una situación como esta:
const characters = ["Poppy", "Barb", "Branch"]; // Define un array
characters.push("Mr. Dinkles"); // Agrega un nuevo índice, sin problemas
console.log(characters) // ["Poppy", "Barb", "Branch", "Mr. Dinkles"]
¿Cuál es la ventaja de usar const? Principalmente que no sobreescribirás el valor por error llevándote a un escenario impredecible en el que puedes no saber de dónde sale, o dicho de otra forma: el código se vuelve más legible. Esta es la ventaja humana, pero también hay una ventaja técnica: Se mejoran los consumos de memoria, aunque en realidad eso es algo menos relevante y se me escapa muchísimo.
Cuando usar let
Cuando vayas a necesitar modificar el valor de una variable. Para poner un ejemplo volvamos al bucle anterior.
for(let i = 0; i < letters.length; i++){
// La i se define con let, así que es modificable y vive
// dentro de este bloque.
}
for(const i = 0; i < letters.length; i++){
// Si la definimos con const, cuando intentamos incrementar
// su valor para pasar a la siguiente iteración, dará un error:
// Uncaught TypeError: Assignment to constant variable.
}
Otro ejemplo habitual sería algo así:
let string = "Esta cadena ? es modificable";
string = string.replace("?", "sí");
console.log(string); // "Esta cadena sí es modificable"
const string = "Esta cadena ? es modificable";
string = string.replace("?", "no");
console.log(string); // Uncaught TypeError: Assignment to constant variable
Conclusiones
- Puedes usar
const
por defecto, y en caso de necesitar modificarlo y cambiar a let
. - Raramente utilizarás
var
, y ante la duda no deberías usarlo. - Definir una variable sin declararla es algo peligroso.
Photo by Raymond Lee on Unsplash