⚡ Curso JavaScript · Nivel N2 Básico

Bloque 4: Arrays y objetos

Hasta ahora tus programas trabajaban con datos sueltos. Hoy aprenden a manejar colecciones (arrays) y fichas con estructura (objetos): la materia prima de toda app real — productos, usuarios, pedidos. Y cuando un array guarda objetos… ya estás modelando el mundo.

⏱ ≈ 12 horas 📚 4 lecciones ✍️ 16 ejercicios con datos reales 📝 Examen final superable (≥ 70 %)
Lección 1 · Teoría

Arrays de verdad

Un array es una lista ordenada de valores entre corchetes. Cada valor ocupa una posición numerada llamada índice, que empieza en 0.

anatomía de un array
const dias = ["lunes", "martes", "miércoles"];

console.log(dias[0]);     // "lunes" — ¡el primero es el 0!
console.log(dias[2]);     // "miércoles"
console.log(dias.length); // 3 — length SIEMPRE es el nº de elementos

const mixto = [42, "texto", true, [1, 2]]; // admite cualquier mezcla
⚠️ Trampa clásica: el último elemento está en length - 1. Para un array de 3 elementos los índices válidos son 0, 1 y 2; pedir dias[3] devuelve undefined (no da error).

1.1 · Mutar: push y pop

Aunque el array se declare con const, su CONTENIDO sí puede cambiar: lo constante es la referencia, no los datos:

añadir y quitar por el final
const carrito = ["teclado"];

carrito.push("ratón");   // añade AL FINAL → ["teclado", "ratón"]
carrito.push("monitor");
carrito.pop();            // quita EL ÚLTIMO → ["teclado", "ratón"]

carrito[0] = "teclado mecánico"; // sobrescribir una posición
Familia completa de mutadores
MétodoHace…
push(x)añade x al final
pop()extrae el último
shift()extrae el primero
unshift(x)añade x al principio
splice(i, n)elimina n elementos desde la posición i

1.2 · Recorrer: for...of

El bucle estrella para arrays. Nada de índices: te entrega CADA ELEMENTO directamente:

✅ for...of: directo
for (const dia of dias) {
  console.log(dia);
}
for clásico: cuando necesitas i
for (let i = 0; i < dias.length; i++) {
  console.log(i + 1, dias[i]);
}
Lección 2 · Teoría

Métodos de array

Los arrays traen herramientas para buscar, cortar, ordenar y unir sin escribir ni un bucle:

2.1 · Buscar

¿está? ¿dónde está?
const frutas = ["pera", "kiwi", "uva"];

frutas.includes("kiwi");  // true — ¿existe?
frutas.indexOf("uva");   // 2 — ¿en qué índice?
frutas.indexOf("melón"); // -1 — código universal de «no está»

2.2 · Cortar: slice no muta

slice(inicio, fin) devuelve UNA COPIA parcial, sin tocar el original. Ojo: el fin queda EXCLUIDO:

copia segura
const podio = ["Ana", "Bo", "Cy", "Di"];

podio.slice(0, 2); // ["Ana", "Bo"] — el 2 NO entra
podio.slice(-1);    // ["Di"] — negativos: contando desde el final
⚠️ No confundir con splice(i, n), que SÍ muta el original. Regla mnemotécnica: slice = fotocopia, splice = tijeras.

2.3 · Ordenar y unir

sort necesita ayuda con números
const letras = ["c", "a", "b"];
letras.sort();                 // ["a", "b", "c"] ✔ texto ok

const nums = [100, 25, 4];
nums.sort();                   // [100, 25, 4] 💥 ¡ordena como TEXTO!
nums.sort((a, b) => a - b);   // [4, 25, 100] ✔ comparator numérico

nums.join(" · ");              // "4 · 25 · 100" — array → string
💡 El comparator (a, b) => a - b es una arrow function del Bloque 3 actuando como callback: si el resultado es negativo, a va antes que b. Para ordenar al revés, resta al revés: b - a.
Lección 3 · Teoría

Objetos literales

Un objeto agrupa datos relacionados bajo claves con nombre. Si un array es una lista de cajas numeradas, un objeto es un armario con cajones etiquetados:

anatomía de un objeto
const persona = {
  nombre: "Ada",
  edad: 36,
  lenguaje: "JavaScript"
};

console.log(persona.nombre);      // "Ada" — acceso con PUNTO
console.log(persona["edad"]);     // 36 — o con CORCHETES
persona.edad = 37;                // modificar
persona.ciudad = "Madrid";       // añadir propiedad nueva
delete persona.lenguaje;          // borrar
⚠️ Leer una clave que no existe NO da error: devuelve undefined. Y los corchetes brillan cuando la clave está en una variable: persona[claveBuscada].

3.1 · Métodos y this

Una función guardada dentro de un objeto se llama método. Dentro de él, la palabra this apunta al propio objeto — «mis datos»:

this = el objeto dueño del método
const cuenta = {
  titular: "Ada",
  saldo: 100,
  ingresar(cantidad) {
    this.saldo += cantidad;   // el saldo DE ESTA cuenta
    return this.saldo;
  },
  describir() {
    return `${this.titular} tiene ${this.saldo} €`;
  }
};

cuenta.ingresar(50);
console.log(cuenta.describir()); // "Ada tiene 150 €"

3.2 · Inspeccionar un objeto

claves, valores y recorridos
Object.keys(persona);    // ["nombre", "edad", "ciudad"]
Object.values(persona);  // ["Ada", 37, "Madrid"]

for (const clave of Object.keys(persona)) {
  console.log(clave, "→", persona[clave]);
}
💡 Diferencia clave: for...of recorre ARRAYS (sus valores); para recorrer las CLAVES de un objeto usa Object.keys() + for...of.
Lección 4 · Teoría

Listas de objetos, spread y JSON

La combinación ganadora del mundo real: arrays de objetos. Cada elemento es una ficha completa:

un catálogo de verdad
const catalogo = [
  { id: 1, nombre: "Teclado", precio: 25 },
  { id: 2, nombre: "Monitor", precio: 199 },
  { id: 3, nombre: "Ratón", precio: 15 }
];

catalogo[1].nombre;         // "Monitor" — índice primero, luego punto
catalogo[0].precio * 2;    // 50

4.1 · Callbacks al poder: map, filter, find, reduce

Aquí brilla el Bloque 3: estos métodos reciben UNA FUNCIÓN y devuelven resultados nuevos sin mutar nada:

los cuatro mosqueteros
catalogo.filter((art) => art.precio < 50);
// → array NUEVO con los que cumplen: Teclado y Ratón

catalogo.map((art) => art.nombre.toUpperCase());
// → ["TECLADO", "MONITOR", "RATÓN"] — misma longitud, transformado

catalogo.find((art) => art.id === 2);
// → el PRIMER objeto que cumple (o undefined)

catalogo.reduce((total, art) => total + art.precio, 0);
// → 239 — acumula todo en UN valor (el 0 es el punto de partida)
Cheat-sheet mental
MétodoPregunta que respondeDevuelve
filter¿cuáles cumplen?array (subconjunto)
map¿cómo es cada uno transformado?array (misma longitud)
find¿cuál es el primero que cumple?elemento o undefined
reduce¿cómo lo resumo a un valor?lo que acumules

4.2 · Spread: copiar sin dolor

los tres puntos …
const base = [1, 2, 3];
const copia = [...base, 4];   // [1, 2, 3, 4] — original intacto

const ada = { nombre: "Ada", edad: 36 };
const ada2026 = { ...ada, ciudad: "Madrid" };
// objeto nuevo con TODO lo anterior + lo nuevo

4.3 · JSON: el idioma de internet

JSON (JavaScript Object Notation) es el formato universal para enviar datos entre servidor y navegador. Dos funciones hacen toda la magia:

objeto → texto
const texto = JSON.stringify(ada);
// '{"nombre":"Ada","edad":36}'
texto → objeto
const obj = JSON.parse(texto);
// { nombre: "Ada", edad: 36 }
⚠️ En JSON las claves SIEMPRE van entre comillas dobles y no hay funciones ni undefined. Es un formato de DATOS puros.
🎉 Con esto ya sabes modelar cualquier dominio: catálogos, usuarios, pedidos… El Bloque 5 conecta estos datos con la página: DOM y eventos, JavaScript tocando HTML de verdad.
Práctica guiada

✍️ Los 16 ejercicios del bloque

Crea la carpeta js-b4/ y resuelve en orden. Archivos ej01.html, ej02.html… con un <script> al final del body; mira los resultados en consola (F12).

Sección A · Arrays de verdad

1 Lista de la compra

Crea compra con tres alimentos, muestra el array completo y su length.

Ver solución
const compra = ["pan", "leche", "huevos"];

console.log(compra);
console.log(`Total: ${compra.length} productos`);

2 El índice manda

Muestra el primer y el último elemento de compra usando índices (el último con length - 1). Sobrescribe el segundo producto.

Ver solución
const compra = ["pan", "leche", "huevos"];

console.log(compra[0]);
console.log(compra[compra.length - 1]);

compra[1] = "leche deslactosada";
console.log(compra);

3 Carrito dinámico

Empieza con un carrito vacío. Añade dos productos con push, quita el último con pop y añade uno al principio con unshift. Logea el estado tras cada paso.

Ver solución
const carrito = [];

carrito.push("teclado");
console.log(carrito);
carrito.push("monitor");
console.log(carrito);

carrito.pop();
console.log(carrito);

carrito.unshift("ratón");
console.log(carrito); // ["ratón", "teclado"]

4 Pasador de diapositivas

Con peliculas de cuatro títulos, recórrelo con for...of imprimiendo «▶ Ahora: ___». Después recórrelo con for clásico numerando desde 1.

Ver solución
const peliculas = ["Coco", "Up", "Wall-E", "Brave"];

for (const peli of peliculas) {
  console.log(`▶ Ahora: ${peli}`);
}

for (let i = 0; i < peliculas.length; i++) {
  console.log(`${i + 1}. ${peliculas[i]}`);
}

5 Detector de stock

Con inventario = ["tornillo", "tuerca", "arandela"]: comprueba con includes si hay «tuerca»; localiza con indexOf la posición de «arandela» y la de «martillo».

Ver solución
const inventario = ["tornillo", "tuerca", "arandela"];

console.log(inventario.includes("tuerca"));    // true
console.log(inventario.indexOf("arandela"));  // 2
console.log(inventario.indexOf("martillo"));  // -1

Sección B · Métodos de array

6 Fotocopia o tijeras

Demostra la diferencia: saca una copia del podio con slice(0, 2) sin tocar el original; luego elimina al tercero del original con splice(2, 1). Logea ambos arrays al final.

Ver solución
const podio = ["Ana", "Bo", "Cy", "Di"];

const finalistas = podio.slice(0, 2);
podio.splice(2, 1);

console.log(finalistas); // ["Ana", "Bo"]
console.log(podio);       // ["Ana", "Bo", "Di"]

7 Ranking numérico

Ordena [100, 25, 4, 250, 7] de menor a mayor con sort y comparator flecha; luego de mayor a menor. Guarda ambas versiones en constantes distintas.

Ver solución
const tiempos = [100, 25, 4, 250, 7];

const asc = [...tiempos].sort((a, b) => a - b);
const desc = [...tiempos].sort((a, b) => b - a);

console.log(asc);
console.log(desc);

8 Etiqueta generada

Une ["JS", "CSS", "HTML"] en la frase «Stack: JS · CSS · HTML» usando join.

Ver solución
const stack = ["JS", "CSS", "HTML"];

console.log(`Stack: ${stack.join(" · ")}`);

Sección C · Objetos literales

9 Ficha de personaje

Crea heroe con nombre, nivel, vida y arma. Muestra la ficha con template literal accediendo por punto.

Ver solución
const heroe = {
  nombre: "Kira",
  nivel: 7,
  vida: 85,
  arma: "espada láser"
};

console.log(`${heroe.nombre} · nv ${heroe.nivel} · ${heroe.vida} PV · ${heroe.arma}`);

10 Evolución del objeto

Sobre heroe: sube el nivel, añade la propiedad escudo, borra arma con delete y logea el objeto resultante. Comprueba también qué devuelve leer una clave inexistente.

Ver solución
heroe.nivel = 8;
heroe.escudo = 40;
delete heroe.arma;

console.log(heroe);
console.log(heroe.mana); // undefined: no existe, pero no rompe

11 El objeto que habla

Añade a cuenta (Lección 3.1) un método retirar(cantidad) que reste de this.saldo solo si hay fondos, devolviendo true/false. Pruébalo con un retiro mayor que el saldo y otro válido.

Ver solución
const cuenta = {
  titular: "Ada",
  saldo: 100,
  retirar(cantidad) {
    if (cantidad > this.saldo) {
      return false;
    }
    this.saldo -= cantidad;
    return true;
  }
};

console.log(cuenta.retirar(500)); // false
console.log(cuenta.retirar(30));   // true
console.log(cuenta.saldo);         // 70

12 Radiografía del objeto

Crea coche con marca, modelo y año anidados dentro de una propiedad ficha. Lista sus claves con Object.keys, sus valores con Object.values y recorre las claves imprimiendo «clave → valor».

Ver solución
const coche = {
  marca: "Cupra",
  ficha: { modelo: "Born", ano: 2024 }
};

console.log(Object.keys(coche));
console.log(Object.values(coche));

for (const clave of Object.keys(coche)) {
  console.log(`${clave} → ${JSON.stringify(coche[clave])}`);
}

Sección D · Listas de objetos (datos reales)

13 Catálogo mínimo

Crea catalogo con tres objetos producto (id, nombre, precio). Muestra el nombre del segundo producto y el precio del primero multiplicado por dos.

Ver solución
const catalogo = [
  { id: 1, nombre: "Teclado", precio: 25 },
  { id: 2, nombre: "Monitor", precio: 199 },
  { id: 3, nombre: "Ratón", precio: 15 }
];

console.log(catalogo[1].nombre);       // Monitor
console.log(catalogo[0].precio * 2);   // 50

14 Filtro de gangas

Usa filter para obtener los productos de menos de 50 € del catálogo y logea cuántos son.

Ver solución
const gangas = catalogo.filter((art) => art.precio < 50);

console.log(gangas);
console.log(`Ofertas: ${gangas.length}`); // 2

15 Transformar, encontrar, resumir

Con el mismo catálogo: ① map a nombres en mayúsculas; ② find del producto con id 2; ③ reduce del precio total.

Ver solución
const vocing = catalogo.map((art) => art.nombre.toUpperCase());
const buscado = catalogo.find((art) => art.id === 2);
const total = catalogo.reduce((suma, art) => suma + art.precio, 0);

console.log(vocing);
console.log(buscado.nombre, buscado.precio);
console.log(`Total: ${total} €`); // 239 €

16 🏆 Proyecto integrador: inventario-tienda.html

Crea inventario-tienda.html. Requisitos mínimos:

  • Un objeto tienda con al menos una propiedad array y un método que use this (p. ej. vender(articulo)).
  • Al menos dos arrays con datos creados con literal […].
  • Recorrido con for...of.
  • Mutación con push o similar.
  • Búsqueda con includes/indexOf/find.
  • Transformación con map/filter/reduce.
  • Exporta la ficha con JSON.stringify y logéala.
Ver solución modelo
const tienda = {
  nombre: "TecnoStore",
  ventas: ["teclado", "ratón"],
  precios: [25, 15, 199],
  vender(articulo, precio) {
    this.ventas.push(articulo);
    this.precios.push(precio);
    return this.ventas.length;
  }
};

for (const venta of tienda.ventas) {
  console.log(`Vendido: ${venta}`);
}

console.log(tienda.precios.includes(199));
const baratos = tienda.precios.filter((p) => p < 50);
const etiquetas = tienda.ventas.map((v) => v.toUpperCase());

tienda.vender("webcam", 39);
console.log(baratos, etiquetas);
console.log(JSON.stringify(tienda));
Evaluación

📝 Examen del Bloque 4

Necesitas ≥ 70 % (10/14) para superar el bloque.

1 · ¿Cómo se crea un objeto literal?
2 · La forma habitual de leer una propiedad es…
3 · Leer una clave que NO existe devuelve…
4 · Un método es…
5 · Dentro de un método, this apunta a…
6 · Los índices de un array empiezan en…
7 · [10, 20, 30].length vale…
8 · push() añade un elemento…
9 · ¿Cuál NO muta el array original?
10 · arr.includes(x) devuelve…
11 · Para ordenar números de menor a mayor hace falta…
12 · map() devuelve…
13 · find() devuelve…
14 · JSON.stringify(obj) sirve para…

Parte B · Reto práctico final

Construye el ejercicio 16 («inventario-tienda.html») sin mirar soluciones y valida tú mismo/a estos criterios. Mínimo para aprobar: 7 de 8 casillas.

Cumplidos: 0 / 8

🎉 ¿Superaste las dos partes? Enhorabuena: has aprobado el Bloque 4 de JavaScript. Ya modelas el mundo real con colecciones y fichas estructuradas. En el Bloque 5 esos datos salen a escena: DOM y eventos, JavaScript manipulando HTML de verdad.