Variables y tipos de datos

Aprende a declarar variables con var, let y const, y entiende los tipos de datos primitivos de JavaScript: string, number, boolean, null, undefined y symbol.

Las variables son contenedores con nombre donde almacenas datos. En JavaScript hay tres formas de declararlas, y elegir la correcta marca la diferencia entre código predecible y código que te da sorpresas.


var, let y const

var — el antiguo (evítalo)

var nombre = 'Ana';
var nombre = 'Luis'; // se puede redeclarar sin error — problema

var tiene ámbito de función, no de bloque. Esto significa que una variable declarada dentro de un if o un for es visible fuera de él. Ese comportamiento inesperado es la raíz de muchos bugs históricos de JavaScript.

let — para valores que cambian

let contador = 0;
contador = 1;    // se puede reasignar
// let contador = 2; // error: no se puede redeclarar en el mismo ámbito

let tiene ámbito de bloque: la variable solo existe dentro de las llaves {} donde se declaró.

const — para valores que no cambian

const PI = 3.14159;
// PI = 3; // error: no se puede reasignar

const también tiene ámbito de bloque. La variable debe inicializarse en la declaración y no se puede reasignar. Úsala por defecto — si luego necesitas reasignar, cámbiala a let.

Regla práctica: usa const siempre. Cambia a let solo si necesitas reasignar. Nunca uses var.


Tipos de datos primitivos

JavaScript tiene exactamente 7 tipos primitivos: string, number, boolean, null, undefined, symbol y bigint. Los cinco primeros son los del día a día. Los dos últimos tienen usos más específicos y los verás con menos frecuencia.

String — texto

const saludo = 'Hola, mundo';
const nombre = "JavaScript";
const mensaje = `Hola, ${nombre}`; // template literal — el más útil

Las comillas simples y dobles son equivalentes. Los backticks (`) permiten interpolar variables con ${} y escribir texto multilínea.

Number — números

const entero   = 42;
const decimal  = 3.14;
const negativo = -100;
const resultado = 10 / 3; // 3.3333...

// Valores especiales
const infinito   = Infinity;
const noEsNumero = NaN; // resultado de operaciones inválidas como 'texto' * 2

JavaScript no distingue entre enteros y decimales — todo es Number. Puede representar con precisión enteros hasta 2⁵³ - 1. Para números más grandes existe BigInt.

Boolean — verdadero o falso

const activo = true;
const logueado = false;

const esMayor = 18 > 10; // true
const sonIguales = 5 === '5'; // false (distinto tipo)

null — ausencia intencional de valor

let usuario = null; // "aquí no hay usuario, y eso es deliberado"

undefined — valor no asignado

let precio; // declarada pero no inicializada
console.log(precio); // undefined

function saludar(nombre) {
  console.log(nombre); // undefined si se llama sin argumentos
}

La diferencia: null lo pones tú intencionalmente. undefined lo pone JavaScript cuando algo no tiene valor.

Symbol — identificadores únicos e irrepetibles

Introducido en ES6. Cada Symbol() crea un valor garantizadamente único, aunque le des la misma descripción:

const id1 = Symbol('id');
const id2 = Symbol('id');

id1 === id2 // false — son distintos aunque tengan el mismo texto

Se usa principalmente para crear claves de propiedades de objetos que no colisionen con otras (por ejemplo, en librerías que necesitan añadir metadatos a objetos de terceros sin riesgo de sobrescribir nada). En el desarrollo cotidiano lo verás poco, pero es importante saber que existe y por qué typeof Symbol('x') devuelve 'symbol'.

BigInt — enteros de tamaño arbitrario

Introducido en ES2020. Permite trabajar con enteros más grandes que Number.MAX_SAFE_INTEGER (2⁵³ - 1 = 9.007 billones). Se escribe con una n al final:

const grande = 9007199254740993n;
const normal = 9007199254740993; // pierde precisión con Number normal

grande + 1n   // 9007199254740994n — exacto
// grande + 1 // TypeError: no se pueden mezclar BigInt y Number

En la práctica lo necesitas en criptografía, IDs de bases de datos muy grandes (algunos sistemas usan IDs de 64 bits) o cálculos financieros de alta precisión. Para el 99% del trabajo web, Number es suficiente.


Comprobar el tipo: typeof

typeof 'hola'       // 'string'
typeof 42           // 'number'
typeof true         // 'boolean'
typeof undefined    // 'undefined'
typeof null         // 'object'  ← bug histórico de JS, no lo cambiarán
typeof {}           // 'object'
typeof []           // 'object'
typeof function(){} // 'function'

Aquí hay tres resultados que sorprenden al principio:

typeof {} y typeof [] devuelven 'object' porque los objetos y los arrays no son tipos primitivos — son tipos de referencia. Los 7 primitivos que acabamos de ver (string, number, boolean, null, undefined, symbol, bigint) son valores simples e inmutables. Un objeto {} o un array [] son estructuras que pueden contener múltiples valores y se almacenan de forma diferente en memoria.

El hecho de que arrays y objetos sean lo mismo para typeof tiene una implicación práctica: si necesitas saber si algo es un array de verdad, no uses typeof — usa Array.isArray():

typeof []        // 'object' — no te dice nada útil
Array.isArray([]) // true    — esto sí
Array.isArray({}) // false

typeof function(){} devuelve 'function' aunque técnicamente las funciones también son objetos en JavaScript (puedes añadirles propiedades, pasarlas como argumentos, devolverlas desde otras funciones). typeof hace una excepción especial para las funciones y les devuelve 'function' en lugar de 'object' — es más útil para detectarlas.

En resumen: typeof te dice si algo es un primitivo (y cuál), o si es una función. Para cualquier otra cosa devuelve 'object', y entonces necesitas herramientas más específicas como Array.isArray() o instanceof.


Conversión de tipos

JavaScript convierte tipos automáticamente en muchas situaciones — esto se llama coerción y es fuente de confusión:

'5' + 3    // '53'  — el número se convierte a string
'5' - 3    // 2     — el string se convierte a número
true + 1   // 2     — true es 1
false + 1  // 1     — false es 0

Para convertir explícitamente:

Number('42')      // 42
Number('hola')    // NaN
String(100)       // '100'
Boolean(0)        // false
Boolean('')       // false
Boolean('texto')  // true
Boolean(1)        // true

Los valores que se convierten a false se llaman falsy: 0, '', null, undefined, NaN, false. Todo lo demás es truthy.

En la siguiente lección vemos los operadores: las herramientas para trabajar con estos valores y construir expresiones.