Variables y tipos de datos
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
constsiempre. Cambia aletsolo si necesitas reasignar. Nunca usesvar.
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:
typeofte 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 comoArray.isArray()oinstanceof.
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
falsese 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.