javascript-variables-var

La antigua var

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”.

javascript-var

Dijeron vamos a hacerlo grachioooocho

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 bloque if 😮
  • Esto es debido a que var tiene un alcance de función, es decir, existe en toda la función ejemplo.

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 a console.log.

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ísticalet/constvar
AlcanceBloqueFunción
HoistingNo
Declaración múltipleNo

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