DEV Community

Cover image for Fundamentos de JavaScript - Variables: La Base de Cualquier Programa
Martín Aguirre
Martín Aguirre

Posted on

Fundamentos de JavaScript - Variables: La Base de Cualquier Programa

Introducción

Como concepto fundamental en todo lenguaje de programación, las variables son la base de cualquier programa. Nos permiten almacenar y manipular datos que luego serán utilizados en nuestro programa. Como recurso útil, las variables son ubicaciones abstractas de almacenamiento, identificadas por un nombre asociado que contiene un valor.

Declarando Variables: const, let & var

Para crear una variable en JavaScript, debemos declararla, lo cual es el término apropiado para esta acción. JavaScript nos proporciona tres palabras clave para declarar variables: var, let y const.

Declaration of a Variable with var

Declaración de una Variable con var

La palabra var se usa para declarar variables con alcance de función o de alcance global, opcionalmente con un valor inicializado.

Principales características de var:

  • Agregada durante la creación de JavaScript en 1995.
  • Tiene alcance o ámbito de función (no de bloque).
  • Puede redeclararse en el mismo ámbito sin errores.
  • Se eleva al principio de su ámbito (hoisting) y se inicializa con undefined.

Ejemplo simple:

var car = "Mercedes";

var car = "Volkswagen"; // La redeclaración funciona
console.log(car) // Imprime: Volkswagen
Enter fullscreen mode Exit fullscreen mode

Nevertheless, this sort of generous flexibility may lead to bugs or glitches in larger programs or systems. The use of this approach is not advised, unless you have a very good reason to do so.

Sin embargo, esta suerte de flexibilidad generosa puede provocar errores o fallos en programas o sistemas más grandes. No se recomienda usar este enfoque, a menos que exista una buena razón para hacerlo.

Declaración de una Variable con let

La palabra let se utiliza para declarar una variable reasignable y de alcance o ámbito local de bloque, opcionalmente inicializada con un valor.

Principales características de let:

  • Agregada en ES6 (2015).
  • Tiene ámbito de bloque (más seguro que var).
  • No se puede redeclarar en el mismo ámbito.
  • Se puede reasignar.

Un ejemplo simple de cómo declarar una variable sin valor, o al menos no todavía:

let varName;
Enter fullscreen mode Exit fullscreen mode

En un sentido técnico, esta variable varName es undefined (indefinida), por lo que le asignaremos un valor:

varName = "Casa";
Enter fullscreen mode Exit fullscreen mode

Como ya ha sido declarada, no volvemos a utilizar la palabra clave let; solo queremos asignarle un valor, así que escribimos el nombre de la variable, agregamos el operador de asignación (=), y asignamos el valor "Casa" que es de tipo string en este caso.

Sin embargo, esto resulta poco práctico. Una forma más sencilla de realizar el trabajo sería la siguiente:

let varName = "Casa";
Enter fullscreen mode Exit fullscreen mode

Utilización de la palabra clave let, nombre de la variable o "identificador", y el valor que se desea asignar.

Siendo más claro y conciso:

let color = "azul";

// let color = "rojo"; Error: Ya ha sido declarada

color = "rojo"; // La reasignación funciona
console.log(color); // Imprime: "rojo"
Enter fullscreen mode Exit fullscreen mode

Ejemplos adicionales de variables con la palabra clave let:

let myDog = "Pipo";
console.log(myDog) // Imprime: "Pipo"

let streetNum = 477
console.log(streetNum) // Imprime: 477

let isFalse = false
console.log(isFalse) // Imprime: false
Enter fullscreen mode Exit fullscreen mode

Como habrás notado, existe una forma estándar de escribir los nombres que asignamos a nuestras variables. En JavaScript, este método se conoce como camelCase. Esta convención tipográfica permite escribir frases sin espacios, donde la primera letra de cada palabra se escribe en mayúscula, excepto la primera letra del compuesto completo. Nos beneficiamos de ella facilitando así la lectura de elementos como variables y funciones.

Declaration de una Variable con const

La palabra const se utiliza para declarar una variable local con alcance de bloque. El valor de una constante debe asignarse cuando se la inicializa y no puede modificarse mediante reasignación con el operador de asignación. Sin embargo, si dicha constante es un objeto, su propiedad puede añadirse, actualizarse o eliminarse.

Se recomienda declarar una variable con const cuando se sabe con certeza que su valor no cambiará.

Características principales de const:

  • También agregada en ES6 (2015).
  • Tiene alcance de bloque.
  • No se puede redeclarar ni reasignar.
  • Debe inicializarse en el momento de la declaración.
const pi = 3.1416;

// pi = 3.14; ✖️ Error: reasignación no permitida
console.log(pi); // Imprime: 3.1416
Enter fullscreen mode Exit fullscreen mode

Nota: const hace que la vinculación de la variable sea inmutable, NO el valor en sí mismo.
Si el valor es un objeto o una matriz (array), su contenido puede cambiar:

const myArr = [1, 2, 3];

myArr.push(4); // ✔️ Permitido - Se modifica el contenido
console.log(myArr); // Imprime: [1, 2, 3, 4]

myArr = [5, 6, 7]; // ✖️ error: Reasignación a una constante
Enter fullscreen mode Exit fullscreen mode

Si bien podemos modificar el contenido de la matriz (agregar, eliminar o cambiar elementos), no podemos reasignar la matriz completa a un nuevo valor.


Ámbito de las Variables (Scope)

Un ámbito es la región de código donde una variable es accesible. Pensemos en esto como el contexto actual de ejecución donde los valores y las expresiones son visibles o se puede hacer referencia a ellos.

Ámbito Global (Global Scope)

Las variables declaradas globalmente, es decir, aquellas variables declaradas por fuera de cualquier bloque o función, tienen algo llamado ámbito global (O, global scope). Estas variables globales pueden ser accedidas desde cualquier lugar en un programa en JavaScript.

Las variables declaradas con var, let o const comparten ciertas similitudes cuando se declaran por fuera de un bloque. Todas tienen un ámbito global:

var myName = "Martin"; // Ámbito global

let currentYear = 2025 // Ámbito global

const isDeveloper = true // Ámbito global
Enter fullscreen mode Exit fullscreen mode

Ejemplo Adicional

Esta variable declarada fuera de la función, se convierte en global:

let treeName = "Ceibo";
// La variable treeName puede ser usada aquí sin problemas

function printTreeName() {
  // La variable treeName puede ser usada aquí también!
}

// La variable treeName puede ser usada incluso después de la función
Enter fullscreen mode Exit fullscreen mode

Las Variables Globales Tienen Ámbito Global:

Todos los scripts y funciones de la misma página web pueden acceder a una variable con alcance global.
En los navegadores, las variables globales declaradas con var se convierten automáticamente en propiedades del objeto window (o globalThis en JavaScript moderno).
Las variables globales declaradas con let o const no se adjuntan a window, pero siguen siendo accesibles en cualquier parte del script.
Demasiadas variables globales pueden provocar conflictos de nombres (dos scripts que usan el mismo nombre de variable se sobrescriben accidentalmente).
Depender de variables globales dificulta la depuración y el mantenimiento del código, ya que cualquier parte del programa puede modificarlas inesperadamente.
Práctica recomendada: limite las variables globales utilizando funciones, módulos o el alcance de bloque.

Ámbito de Función (var)

Las variables declaradas con var son visibles en toda la función donde están definidas, incluso fuera de los bloques.

Ejemplo rápido:

function testVar() {
  if (true) {
    var message = "Hola desde var!";
  }
  console.log(message); // ✔️ Funciona (Ámbito de función)
}

testVar(); // Imprime: Hola desde var
Enter fullscreen mode Exit fullscreen mode

Sin embargo, las variables definidas dentro de una función no son accesibles (visibles) desde fuera de ella. Esto incluye var, let y const. Todas tienen ámbito de función.

function myDogName() {
  var dogName = "Fido"; // Ámbito, o alcance, de función
  console.log(dogName);
}

function myAgeNumber() {
  var myAge = 25; // Ámbito, o alcance, de función
  console.log(myAge);
}

function isFunctionScoped() {
  var functionScoped = true; // Ámbito, o alcance, de función
  console.log(functionScoped);
}
Enter fullscreen mode Exit fullscreen mode

Con esto, podemos afirmar claramente que las variables declaradas dentro de una función de JavaScript son locales a la función en términos de alcance.

// La variable carColor no puede usarse aquí

function getCarProps() {
  let carColor = "grey";

  // La variable carColor puede usarse aquí sin problemas
}

// La variable carColor no puede usarse aquí
Enter fullscreen mode Exit fullscreen mode

Las Variables Locales Tienen Ámbito de Función

  • Se puede acceder a ellas únicamente desde dentro de la función.
  • Ningún script ni función externa a la función puede acceder a ellas.
  • Las variables con el mismo nombre se pueden usar fuera de la función.
  • Las variables con el mismo nombre se pueden usar en diferentes funciones.
  • Las variables locales se crean al iniciar una función.
  • Las variables locales se eliminan al finalizar la función.
  • Los argumentos (parámetros) funcionan como variables locales dentro de las funciones.

Ámbito de Bloque, o Block Scope (let & const)

Las variables declaradas con let o const solo son accesibles dentro del bloque ({ ... }) donde están definidas. Este enfoque proporciona una organización y estructuración del código mucho mejor, evitando así sobrescrituras no deseadas de variables y errores inesperados.

function testLetAndConst() {
  if (true) {
    let msg1 = "Hola desde let";
    const msg2 = "Hola desde const";
    console.log(msg1); // ✔️ Funciona
    console.log(msg2); // ✔️ Funciona
  }
  // console.log(msg1); ✖️ Error: msg1 no está definido
  // console.log(msg2); ✖️ Error: msg2 no está definido
}

testLetAndConst();
Enter fullscreen mode Exit fullscreen mode

Notas

  • Las variables declaradas con la palabra clave var no pueden tener alcance de bloque.
  • Las variables declaradas con la palabra clave var, dentro de un bloque { ... }, son accesibles desde fuera del bloque.

Sintetizada

  • var tiene la particularidad de ignorar los límites de bloque. Sin embargo, está limitado por funciones.

  • let y const respetan los límites de bloque. Por lo tanto, son un enfoque más seguro y predecible.

Una tabla fácil de seguir para comprender mejor estos conceptos relacionados con el ámbito o alcance:

Palabra Ámbito Redeclaración Elevación (Hoisting) Notas
var Función ✔️ Sí ✔️ Con undefined Código 'legacy', evitar en lo posible
let Bloque ✖️ No ✔️ Sin inicialización (TDZ) Utilizar para valores mutables
const Bloque ✖️ No ✔️ Sin inicialización (TDZ) Utilizar por defecto

Hoisting, o 'Elevación'

La Elevación, o Hoisting es un comportamiento predeterminado de JavaScript que consiste en el proceso mediante el cual el intérprete mueve la declaración de funciones, variables, clases o importaciones a la parte superior de su ámbito, antes de la ejecución del código.

Las Declaraciones de Variables se Elevan

En JavaScript, podemos declarar una variable después de usarla; es decir, una variable puede usarse antes de ser declarada.

Los dos ejemplos siguientes darán el mismo resultado.

Ejemplo 1:

animal = "perro"; // Asignando "perro" a animal

console.log(animal); // Imprime: "perro"

var animal; // Declaración
Enter fullscreen mode Exit fullscreen mode

Ejemplo 2:

var animal; // Declaración

animal = "dog"; // Asignando "perro" a animal

console.log(animal); // Imprime: "perro"
Enter fullscreen mode Exit fullscreen mode

Las variables declaradas con var se elevarán, lo que significa que se puede hacer referencia a ellas desde cualquier lugar dentro de su ámbito respectivo. Sin embargo, si se intenta acceder a una variable antes de que se haya declarado, su valor predeterminado siempre será undefined. Teniendo esto en cuenta, podemos afirmar que solo su declaración e inicialización predeterminada se elevarán, pero no su valor mediante asignación.

console.log(tree); // undefined, o indefinido

var tree = "Pino";

function printColor() {
  console.log(color); // undefined, o indefinido
  var color = "Carmesí";
}

printColor();
Enter fullscreen mode Exit fullscreen mode

Como ejemplo adicional:

var tree;

console.log(tree); // undefined, o indefinido

tree = "Pino";

function printColor() {
  var color;
  console.log(color); // undefined, o indefinido
  var color = "Carmesí";
}

printColor();
Enter fullscreen mode Exit fullscreen mode

El Comportamiento de Elevación, o Hoisting, en let y const

A diferencia de var, las palabras clave let y const tienen su propio mecanismo de elevación: Se elevan al principio del bloque (lo que significa que JavaScript sabe que existen), pero permanecen sin inicializar hasta que la ejecución del código llega a su línea de declaración. Esto difiere de var, que se eleva y se inicializa automáticamente con undefined.

Intentar utilizar una variable let antes de su declaración adecuada dará como resultado un ReferenceError (error de referenciación).

Hasta que se procese la declaración, la variable permanecerá en una "zona muerta temporal". Esta Zona Muerta Temporal es el período entre la entrada en el ámbito donde se declara la variable y la declaración real. Durante este tiempo, la variable técnicamente existe en memoria, pero no se puede acceder a ella, lo que genera un error de referencia (ReferenceError) si se intenta usar.

console.log(dog); // ReferenceError
let dog = "Mastín";

console.log(cat); // ReferenceError
let cat = "Persa";
Enter fullscreen mode Exit fullscreen mode

Veamos otro ejemplo:

console.log(year);

displayYear();

function displayYear() {
  console.log("El año es ", year);
}

let year = 2025;
Enter fullscreen mode Exit fullscreen mode

Salida:

Uncaught ReferenceError: year is not defined
Enter fullscreen mode Exit fullscreen mode

A diferencia de las declaraciones con var, que se inicializan durante su creación con undefined como valor predeterminado, year no tiene referencia a su valor en memoria. Debido a este pequeño detalle, se genera un error de referencia, como se ve en el ejemplo.

Ahora, volviendo al concepto de "zona muerta temporal", lo examinaremos con más detalle:

  • Zona muerta temporal en cuestión:
  console.log(year);

  displayYear();

  function displayYear() {
    console.log("El año es ", year);
  }
Enter fullscreen mode Exit fullscreen mode
  • Fin de la zona muerta temporal:
  let year = 2025;
Enter fullscreen mode Exit fullscreen mode

Forma correcta de utilizar la metodología let:

let year = 2025;
console.log(year);

function displayYear() {
  console.log("El año es ", year);
}

displayYear();
Enter fullscreen mode Exit fullscreen mode

Además, también podemos ver que la zona muerta temporal puede proporcionarnos un claro beneficio a la hora de evitar sobrescrituras accidentales:

let fruit = "Manzana";

if (true) {
  // Aquí comienza la zona muerta temporal para la variable fruta en ámbito de bloque
  console.log(fruit); // ReferenceError
  let fruit = "Banana";
}
Enter fullscreen mode Exit fullscreen mode

Por otro lado, tenemos la palabra clave const:

const horseName;
console.log(horseName)
Enter fullscreen mode Exit fullscreen mode

Salida:

Uncaught SyntaxError: Missing initializer in const declaration
Enter fullscreen mode Exit fullscreen mode

Dado que una constante no puede cambiar su valor mediante asignación ni redeclararse mientras el programa se está ejecutando, debe inicializarse con un valor.

Uso correcto de const:

const horseName = "Duque";
console.log(horseName);
Enter fullscreen mode Exit fullscreen mode

Salida:

Duque
Enter fullscreen mode Exit fullscreen mode

Sombreado de Variables (Shadowing)

Lo llamamos así cuando una variable de ámbito interno oculta o anula una variable externa dentro del ámbito local.

let name = "Alicia";

function printName() {
  let name = "Roberto"; 
  console.log(name); // Imprime: Roberto
}

printName();
console.log(name); // Imprime: Alicia
Enter fullscreen mode Exit fullscreen mode

Dos puntos clave a tener en cuenta:

  • var permite la redeclaración, lo que puede generar errores y resultados inesperados.
  • let y const generarán errores si se intenta redeclarar.
var x = 25.4;
var x = 32.7; // Ningún error, simplemente se sobrescribe

let y = 18.3;
let y = 49.7; // SyntaxError: El identificador 'y' ya ha sido declarado
Enter fullscreen mode Exit fullscreen mode

Teniendo en cuenta que el sombreado de variables puede hacernos perder el acceso a la variable original, esta práctica puede generar errores no deseados y resultados inesperados que dificultarán la depuración, ya que no comprenderemos el origen del problema. Siempre es recomendable declarar las variables con un nombre lo más explicativo posible, de modo que describa su propósito por sí mismo y para sí mismo. También se recomienda declarar las variables organizadamente en grupos donde estén cerca unas de otras para que sea más fácil detectar nombres repetidos, en lugar de dispersarlas sin sentido por el código.


Bonus: Buenas Prácticas En Cuanto a Variables

  • Preferir usar const por defecto y luego let cuando se requiera reasignación. Evitar var tanto como sea posible, ya que puede provocar problemas de hoisting, o elevación y comportamientos inesperados. El desarrollo moderno con JavaScript se basa principalmente en let y const.
  • Mantener el alcance de las variables lo más limitado posible (ámbito de bloque > ámbito de función > global).
  • Evitar el shadowing, o sombreado, a menos que sea intencional, obvio y, en última instancia, útil.
  • Minimizar el uso de variables globales. Estas son accesibles desde cualquier lugar, lo que puede causar conflictos de nombres, errores difíciles de encontrar y diferentes tipos de sorpresas desagradables. Desarrollar un gusto por las declaraciones con alcance local.
  • Inicializar las variables al declararlas para mayor claridad. Esto evita que tengan un valor undefined, o indefinido, lo que podría provocar posibles errores.
  • Use nombres descriptivos que resalten el propósito de la variable o los datos que contiene; ya sea global o local, la legibilidad es más importante de lo que cree.
  • Tender a agrupar variables relacionadas. Al conectarlas de forma lógica y sensata, se mejora la legibilidad y se reduce el riesgo de sombreado, o shadowing.

Gracias por tu tiempo.

Si te interesa apoyar mis escritos, podés comprarme un café aquí: PayPal.me/martinxcvi


Foto de portada por Desmond Marshall en Unsplash 📸

Top comments (0)