Variables y tipos
En la lección anterior tu script del saludo ya usaba variables sin que te las explicara en detalle. Escribiste const horaActual = new Date().getHours() y let saludo. Funcionó, pero ahora toca entender qué son las variables, por qué existen y cómo usarlas correctamente. Si recuerdas la sección de Lógica de Programación, ya trabajaste con variables en pseudocódigo — ahora vas a ver cómo se traducen a JavaScript real.
Piensa en esto: todo programa necesita recordar cosas. El nombre del usuario, el precio de un producto, si el carrito está vacío o no, cuántos elementos tiene una lista. Sin variables, cada dato se perdería en el momento en que lo calculas. Las variables son la memoria de tu programa.
¿Qué es una variable?
Una variable es un nombre que le das a un espacio en la memoria del navegador para guardar un valor. Es como una caja con una etiqueta:
const nombreCafeteria = "Café Estelar";
const precioEspresso = 2.50;
const estaAbierta = true;
console.log(nombreCafeteria); // → "Café Estelar"
console.log(precioEspresso); // → 2.5
console.log(estaAbierta); // → true
Tres variables, tres tipos de datos diferentes: texto, número y booleano (verdadero/falso). JavaScript es flexible con los tipos — no tienes que declarar "esto es un número" como en otros lenguajes. Simplemente asignas el valor y JavaScript lo entiende.
const vs let: la regla de oro
En JavaScript moderno tienes dos formas de declarar variables: const y let. La regla es simple:
const: para valores que no van a cambiar. Úsalo siempre por defecto.let: para valores que necesitas reasignar después.
// const: el valor no cambia
const nombreTienda = "Vinyl Paradise";
const impuesto = 0.21;
const urlApi = "https://api.vinylparadise.com";
// let: el valor necesita cambiar
let itemsEnCarrito = 0;
itemsEnCarrito = 1; // ✅ Puedo reasignar
itemsEnCarrito = 3; // ✅ Puedo reasignar otra vez
// ❌ Esto da error: no puedes reasignar un const
const precio = 29.99;
// precio = 34.99; // → TypeError: Assignment to constant variable.
¿Por qué const por defecto? Porque si una variable nunca cambia, tu código es más predecible. Cuando lees const, sabes que ese valor es estable. Cuando lees let, sabes que en algún punto del código ese valor va a cambiar — y prestas más atención.
¿Y var?
var es la forma antigua de declarar variables. Existe desde los orígenes de JavaScript (1995) y todavía funciona, pero tiene problemas de diseño que causan bugs difíciles de encontrar. No la uses. Si la ves en tutoriales o código antiguo, sustitúyela mentalmente por let o const.
// ❌ var: no la uses en código nuevo
var nombre = "antiguo";
// ✅ const o let: siempre
const nombre = "moderno";
Nombres de variables
Hay reglas y hay convenciones. Las reglas las impone JavaScript (si las rompes, error). Las convenciones las impone la comunidad (si las rompes, código feo).
Reglas (obligatorias):
- Pueden contener letras, números,
_y$. - No pueden empezar por un número.
- No pueden ser palabras reservadas (
let,const,if,return, etc.).
Convenciones (recomendadas):
- Usa camelCase:
precioTotal,nombreUsuario,estaActivo. - Nombres descriptivos:
itemsEnCarritoen vez dexodatos. - Booleanos con prefijo:
isActive,hasDiscount,canEdit(o en español:estaActivo,tieneDescuento). - Constantes globales en UPPER_SNAKE_CASE:
MAX_INTENTOS,API_URL.
// ❌ Nombres malos
const x = 29.99;
const d = true;
const arr = ["espresso", "latte"];
// ✅ Nombres buenos
const precioProducto = 29.99;
const tieneDescuento = true;
const bebidasDisponibles = ["espresso", "latte"];
// ✅ Constantes globales
const MAX_ITEMS_CARRITO = 50;
const IVA_ESPANA = 0.21;
Tipos de datos primitivos
JavaScript tiene varios tipos de datos. Los más importantes que vas a usar todos los días:
String (texto)
Cualquier texto entre comillas. Puedes usar comillas simples, dobles o backticks:
const nombre = "Café Estelar"; // Comillas dobles
const eslogan = 'Donde el café es arte'; // Comillas simples
const saludo = `Hola, bienvenido`; // Backticks (template literals)
// Las tres formas son equivalentes para texto simple.
// La convención más común: comillas dobles o simples (elige una y sé consistente).
// Los backticks tienen superpoderes — sigue leyendo.
Number (número)
JavaScript no distingue entre enteros y decimales. Todo es Number:
const edad = 28;
const precio = 3.50;
const temperaturaHelada = -18;
const millones = 1_000_000; // Los guiones bajos son separadores visuales (legible)
console.log(millones); // → 1000000
// Cuidado con los decimales
console.log(0.1 + 0.2); // → 0.30000000000000004 (sí, en serio)
// Esto es un "detalle" de cómo los ordenadores representan decimales.
// Para dinero, trabaja en céntimos: 350 en vez de 3.50
Boolean (verdadero/falso)
Solo dos valores posibles: true o false. Son la base de toda lógica:
const estaAbierta = true;
const tieneStock = false;
const esAdmin = true;
const carritoVacio = true;
// Los booleanos suelen venir de comparaciones
const esMayorDeEdad = edad >= 18; // true si edad es 18 o más
const precioAlto = precio > 100; // false si precio es 3.50
const mismoNombre = nombre === "Café Estelar"; // true
undefined
undefined significa "existe pero no tiene valor asignado". Es el valor por defecto de una variable declarada sin inicializar:
let direccionEntrega;
console.log(direccionEntrega); // → undefined
// También aparece cuando accedes a algo que no existe
const usuario = { nombre: "Luna" };
console.log(usuario.telefono); // → undefined (la propiedad no existe)
null
null significa "existe y deliberadamente no tiene valor". Lo asignas tú para indicar "vacío a propósito":
let cuponAplicado = null; // El usuario todavía no ha metido ningún cupón
// Más tarde, cuando el usuario introduce un cupón:
cuponAplicado = "VERANO25";
// Si lo elimina:
cuponAplicado = null; // Volvemos a "sin cupón"
null vs undefined: la diferencia
Es una de las preguntas más comunes en entrevistas técnicas:
undefined: JavaScript dice "no le has dado valor a esto". Es automático.null: Tú dices "esto está vacío a propósito". Es intencional.
let pedidoActual; // undefined — no hemos asignado nada
let usuarioSeleccionado = null; // null — explícitamente "no hay usuario seleccionado"
// Analogía:
// undefined = una caja que nunca abriste
// null = una caja que abriste y está vacía a propósito
typeof: comprueba el tipo
El operador typeof te dice qué tipo de dato es una variable. Muy útil para depurar:
console.log(typeof "Café Estelar"); // → "string"
console.log(typeof 42); // → "number"
console.log(typeof true); // → "boolean"
console.log(typeof undefined); // → "undefined"
console.log(typeof null); // → "object" 😱
// Sí, typeof null devuelve "object". Es un bug histórico de JavaScript
// desde 1995 que nunca se corrigió por compatibilidad.
// Para comprobar null, usa: valor === null
Usa typeof cuando no estés seguro de qué tipo de dato estás recibiendo. Es especialmente útil cuando trabajas con datos que vienen del usuario o de una API:
const inputUsuario = "42"; // Esto viene de un formulario HTML
console.log(typeof inputUsuario); // → "string" (¡no es un número!)
console.log(inputUsuario + 1); // → "421" (concatena como texto)
// Para convertirlo a número:
const cantidad = Number(inputUsuario);
console.log(typeof cantidad); // → "number"
console.log(cantidad + 1); // → 43
Template literals: texto con superpoderes
Los template literals usan backticks (`) en vez de comillas y tienen dos ventajas enormes:
1. Interpolación de variables
Metes variables dentro del texto con ${...}:
const producto = "Espresso Galáctico";
const precio = 2.50;
const cantidad = 3;
// ❌ Forma antigua: concatenar con +
const mensaje1 = "Has pedido " + cantidad + "x " + producto + " por " + (precio * cantidad) + " €";
// ✅ Template literal: mucho más legible
const mensaje2 = `Has pedido ${cantidad}x ${producto} por ${precio * cantidad} €`;
console.log(mensaje2);
// → "Has pedido 3x Espresso Galáctico por 7.5 €"
Dentro de ${} puedes poner cualquier expresión JavaScript: variables, operaciones, llamadas a funciones, lo que sea.
2. Texto multilínea
// ❌ Con comillas normales necesitas \n
const html1 = "<div>\n <h1>Café Estelar</h1>\n <p>El mejor café</p>\n</div>";
// ✅ Con backticks: saltos de línea reales
const html2 = `
<div>
<h1>Café Estelar</h1>
<p>El mejor café de la galaxia</p>
</div>
`;
console.log(html2);
Esto es especialmente útil cuando generas HTML desde JavaScript (algo que harás constantemente).
Ejemplo completo: ficha de personaje
Vamos a juntar todo lo que has aprendido en un ejemplo práctico: una ficha de stats de un personaje de videojuego.
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Stats del personaje</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="character-card"></div>
<script src="app.js"></script>
</body>
</html>
// Datos del personaje (const porque no cambian durante la partida)
const nombre = "Zara Voidwalker";
const clase = "Hechicera";
const nivel = 42;
const saludMaxima = 850;
const mana = 1200;
const fuerza = 38;
const inteligencia = 95;
// Datos que sí cambian (let)
let saludActual = 720;
let experiencia = 78450;
let estaViva = true;
let objetivoActual = null; // Sin objetivo seleccionado todavía
// Verificaciones con typeof
console.log(typeof nombre); // → "string"
console.log(typeof nivel); // → "number"
console.log(typeof estaViva); // → "boolean"
console.log(typeof objetivoActual); // → "object" (recuerda: typeof null es "object")
// Cálculos derivados
const porcentajeSalud = Math.round((saludActual / saludMaxima) * 100);
const experienciaParaSiguienteNivel = 100000;
const progresoNivel = Math.round((experiencia / experienciaParaSiguienteNivel) * 100);
// Generar la ficha con template literals
const fichaHTML = `
<div class="character-card">
<h1>${nombre}</h1>
<p class="character-class">${clase} — Nivel ${nivel}</p>
<div class="stats">
<div class="stat">
<span class="stat-label">❤️ Salud</span>
<span class="stat-value">${saludActual} / ${saludMaxima} (${porcentajeSalud}%)</span>
</div>
<div class="stat">
<span class="stat-label">🔮 Mana</span>
<span class="stat-value">${mana}</span>
</div>
<div class="stat">
<span class="stat-label">⚔️ Fuerza</span>
<span class="stat-value">${fuerza}</span>
</div>
<div class="stat">
<span class="stat-label">🧠 Inteligencia</span>
<span class="stat-value">${inteligencia}</span>
</div>
</div>
<div class="progress">
<p>Progreso al nivel ${nivel + 1}: ${progresoNivel}%</p>
</div>
<p class="status">Estado: ${estaViva ? "Viva" : "Derrotada"}</p>
<p class="target">Objetivo: ${objetivoActual ?? "Sin objetivo"}</p>
</div>
`;
// Insertar en la página
document.querySelector("#character-card").innerHTML = fichaHTML;
// Log de depuración
console.log(`Personaje: ${nombre}, Nivel: ${nivel}, Salud: ${porcentajeSalud}%`);
Observa varias cosas importantes en este ejemplo:
- Usamos
constpara los stats base que no cambian yletpara los que sí (salud actual, experiencia). objetivoActualempieza comonull(no hay objetivo seleccionado), no comoundefined.- Los template literals generan todo el HTML de la ficha con las variables interpoladas.
innerHTMLinserta HTML completo (a diferencia detextContentque solo inserta texto plano).${estaViva ? "Viva" : "Derrotada"}es un operador ternario — lo verás en la siguiente lección.${objetivoActual ?? "Sin objetivo"}es el operador nullish coalescing — también lo verás pronto.
Conversión de tipos
A veces necesitas convertir un tipo de dato en otro. Esto pasa constantemente cuando trabajas con formularios HTML (todo viene como texto):
// String a Number
const inputEdad = "28";
const edad = Number(inputEdad); // → 28
const edadAlt = parseInt("28"); // → 28 (entero)
const precioAlt = parseFloat("3.50"); // → 3.5 (decimal)
// Number a String
const precio = 42;
const precioTexto = String(precio); // → "42"
const precioTexto2 = precio.toString(); // → "42"
const precioTexto3 = `${precio}`; // → "42" (el truco del template literal)
// A Boolean
const valorVerdadero = Boolean(1); // → true
const valorFalso = Boolean(0); // → false
const textoVerdadero = Boolean("Hola"); // → true
const textoFalso = Boolean(""); // → false
// Cuidado con Number() en textos no numéricos
console.log(Number("hola")); // → NaN (Not a Number)
console.log(Number("")); // → 0
console.log(Number(true)); // → 1
console.log(Number(false)); // → 0
Valores "truthy" y "falsy"
En JavaScript, cualquier valor puede evaluarse como verdadero o falso en un contexto booleano. Estos son los valores falsy (se evalúan como false):
// Todos estos son "falsy" — se evalúan como false
Boolean(false); // false (obvio)
Boolean(0); // false
Boolean(""); // false (string vacío)
Boolean(null); // false
Boolean(undefined); // false
Boolean(NaN); // false
// TODO lo demás es "truthy" — se evalúa como true
Boolean(1); // true
Boolean(-1); // true (cualquier número excepto 0)
Boolean("Hola"); // true (cualquier string no vacío)
Boolean("0"); // true (¡cuidado! el string "0" NO es falsy)
Boolean([]); // true (arrays vacíos son truthy)
Boolean({}); // true (objetos vacíos son truthy)
Esto es importante porque lo vas a usar constantemente en condiciones:
const nombreUsuario = ""; // El usuario no escribió nada
if (nombreUsuario) {
console.log(`Hola, ${nombreUsuario}`);
} else {
console.log("Por favor, introduce tu nombre");
}
// → "Por favor, introduce tu nombre" (porque "" es falsy)
Resumen
constpor defecto,letsolo cuando necesites reasignar. Nuncavar.- Tipos primitivos:
string,number,boolean,null,undefined. typeofpara comprobar el tipo de un valor.null= vacío a propósito.undefined= sin valor asignado.- Template literals (
`${variable}`) para texto con variables y multilínea. - Usa nombres descriptivos en camelCase.
- Todo valor en JavaScript es truthy o falsy.
En la siguiente lección vamos a ver operadores y condicionales — cómo hacer que tu programa tome decisiones.
Crea la ficha de tu personaje favorito
Crea un archivo app.js que genere la ficha de un personaje (de un videojuego, serie, película o inventado) y la muestre en la página:
- Usa al menos 3 variables
const(datos que no cambian: nombre, clase, nivel máximo). - Usa al menos 2 variables
let(datos que podrían cambiar: salud actual, ubicación). - Incluye al menos un
boolean, unnully unnumber. - Usa
typeofen la consola para verificar el tipo de cada variable. - Genera el HTML de la ficha usando template literals con interpolación (
${variable}). - Muestra un porcentaje calculado (por ejemplo: salud actual / salud máxima * 100).
Bonus: añade un pequeño CSS para que la ficha se vea como una tarjeta de videojuego (fondo oscuro, borde con glow, tipografía monoespaciada para los stats).
lightbulb Pistas
Empieza definiendo todas las variables arriba del archivo, luego el template literal con el HTML, y al final el document.querySelector(...).innerHTML. Para el porcentaje, usa Math.round() para evitar decimales largos. Recuerda que innerHTML interpreta HTML, mientras que textContent solo pone texto plano.