En JavaScript las variables se declaran con let
y const
. Eso es así desde ECMAScript 6 (2015). En la actualidad, solo debéis usar estas en vuestro código.
Pero si lleváis un tiempo en el mundo de la programación, o si miráis tutoriales no actualizados (realmente no muy actualizados) encontraréis la sintaxis de var
.
Así que va siendo hora de dejar de ignorar el elefante azul en la sala 🐘, y hablar un poco de la vieja sintaxis var
.
Además francamente es un tema interesante (y hasta divertido), si te apetece ver cómo a veces las cosas no salen del todo bien, y lo difícil que es arreglarlo.
Declaración de variables con var
La palabra clave var
es la sintaxis original para declarar variables en JavaScript desde la primera versión ECMAScript 1.
var edad = 25;
console.log(edad); // 25
En este ejemplo, edad
se declara con var
y se le asigna el valor 25
.
Antes de ES6, var
era la única forma de declarar variables en JavaScript. A priori, parece una sintaxis “bastante normal” 🤷.
Sin embargo, el funcionamiento de las variables var
tenía ciertas “peculiaridades”, que resultaban poco intuitivas para los programadores.
En definitiva, el uso de variables con var
, en lugar de funcionar como lo hacían la mayoría de lenguajes, lo hacía “a su manera”.
Permitidme que le eche un poco de humor al asunto 😊.
Características de var
Vamos a ver cuales eran estas “peculiaridades” 👇
En primer lugar, las variables definidas con var
tienen alcance de función. Esto significa que una variable declarada con var
es accesible en toda la función en la que se declara.
function miFuncion() {
if (true) {
var mensaje = "Hola Mundo";
}
console.log(mensaje); // mensaje está accesible aquí ⚠️
}
miFuncion();
En este ejemplo,
- La variable
mensaje
es accesible fuera del bloqueif
😮 - Esto es debido a que
var
tiene un alcance de función, es decir, existe en toda la funciónejemplo
.
Esto es muy diferente del resto de lenguajes, en el que generalmente el ámbito es a nivel de bloque (lo que está entre {}
).
Otro de las peculiaridades de var
es su comportamiento con el Hoisting. Esto significa que las declaraciones de variables se elevan al inicio de su ámbito, pero las inicializaciones no se elevan.
Como resultado, las variables declaradas con var
son accesibles antes de su declaración, pero su valor será undefined
hasta que se llegue a la línea donde se inicializan.
// accedemos a la variable antes de declararla ⚠️
console.log(nombre); // undefined
var nombre = "Luis";
console.log(nombre); // "Luis"
En este ejemplo,
- La declaración de la variable
nombre
se eleva al principio del contexto de ejecución - Por lo que podemos usar la variable antes de declararla 😮
- Dara un valor
undefined
en la primera llamada aconsole.log
.
Si quieres saber más sobre Hoisting consulta la entrada
Por último, las variables declaradas con var
podían ser volver a declarar dentro del mismo ámbito, sin que ocurra ningún error.
var numero = 5;
var numero = 10; // la vuelvo a declarar
console.log(numero); // 10
Aquí, la segunda declaración de numero
sobrescribe la primera 😮
Las tres cosas de forma independiente eran bastante malas. Pero unidas eran terribles (un auténtico cachondeo hiper peligroso de variables) 🤦.
Las nuevas let
y const
Las peculiaridades de var
son entendibles en la forma en que surgió JavaScript (recursos de las máquinas de la época, sencillez de uso, etc). Francamente, no se esperaba que tuviera tanto impacto como tiene hoy en día.
Pero, a medida que el lenguaje se más importante, esta peculiaridades dificultaban mucho el desarrollo. Sobre todo en proyectos medianos y grandes.
Así que, en la gran renormalización que supuso ES6 aprovecharon para modificar la forma en la que se trabajaba con las variables (pasaron a ser más similares a lo que se encuentra en el resto de lenguajes).
Así surgió let
y const
(que ya conocemos) y que venían, precisamente, para arreglar estos comportamientos que tenía var
.
Característica | let/const | var |
---|---|---|
Alcance | Bloque | Función |
Hoisting | No | Sí |
Declaración múltiple | No | Sí |
Tienen un ámbito de bloque, lo que significa que una variable declarada con let
o const
solo está disponible dentro del bloque en el que se declara, como en un if
o un for
.
function miFuncion() {
if (true) {
let mensaje = "Hola Mundo";
}
console.log(mensaje); // ❌ ReferenceError: mensaje is not defined
}
miFuncion();
También tienen hoisting, pero no se inicializan. Además, se introduce el concepto de Temporal Dead Zone (TDZ).
// accedemos a la variable antes de declararla
console.log(nombre); // ❌ ReferenceError: nombre is not defined
let nombre = "Luis";
console.log(nombre); // "Luis"
Es decir, que si intentamos acceder a una variable declarada con let
o const
antes de su declaración resulta en un ReferenceError
No permiten redeclarar la misma variable en el mismo ámbito. Intentar hacerlo resulta en un SyntaxError
.
let numero = 5;
let numero = 10; // ❌ SyntaxError: Identifier 'numero' has already been declared
En definitiva
Para muchos, el funcionamiento de var
fue un error en el plantamiento de JavaScript, que arrastramos heredada desde sus comienzos
De hecho, parte del “hate” que le cae a veces a JavaScript es por cosas, como el comportamiento de var
(y porque no se han enterado de que las cosas han cambiado).
También hay que tener en cuenta los recursos que tenían las máquinas de la época (1995), en comparación con las que tenemos hoy en día. Así como las mejoras en los intérpretes actuales.
Hoy en día, la declaración de variables con var
sigue siendo funcional. No se puede quitar por motivos de retrocompatibilidad con el código anterior.
A mi me gusta como historia para ilustrar como, a veces, algunas decisiones son muy difíciles de deshacer (porque tienes millones de líneas de código funcionado)
Sin embargo, en la actualidad el uso de var
está totalmente desaconsejado. En su lugar, usar siempre la sintaxis definida en ES6 con let
y const