Tema
Arrays
Casi todo en una aplicación real es una lista: los productos de una tienda, los mensajes de un chat, las tareas pendientes, los resultados de una búsqueda. En JavaScript, las listas se guardan en arrays. En esta lección aprenderás a crearlos, leerlos, modificarlos, recorrerlos y a evitar uno de los errores más confusos para principiantes: la diferencia entre copiar y referenciar.
Concepto
Un array es como una fila de casilleros numerados. Cada casillero guarda un valor y tiene un número (el índice) que empieza en 0, no en 1.
txt
Índice: 0 1 2 3
┌─────────┬──────────┬──────────┬──────────┐
│ 'Café' │ 'Pan' │ 'Leche' │ 'Huevos' │
└─────────┴──────────┴──────────┴──────────┘
length: 4- El primer elemento está en el índice
0. - El último está en el índice
length - 1. - Un array puede guardar cualquier tipo de dato, incluso mezclados (aunque lo ideal es que todos sean del mismo tipo).
Crear arrays
js
// Forma recomendada: corchetes
const frutas = ['manzana', 'pera', 'uva'];
const precios = [120, 45.5, 300];
const vacio = [];
// Mezclando tipos (posible, pero poco recomendable)
const mezcla = ['texto', 42, true, null];
// Arrays de objetos: lo más común en proyectos reales
const productos = [
{ id: 1, nombre: 'Playera', precio: 250 },
{ id: 2, nombre: 'Gorra', precio: 180 },
];
// Otras formas útiles
const cincoCeros = new Array(5).fill(0); // [0, 0, 0, 0, 0]
const letras = Array.from('hola'); // ['h', 'o', 'l', 'a']
const delUnoAlCinco = Array.from({ length: 5 }, (_, i) => i + 1); // [1, 2, 3, 4, 5]Acceder y modificar elementos
js
const colores = ['rojo', 'verde', 'azul'];
// Leer por índice
console.log(colores[0]); // "rojo"
console.log(colores[2]); // "azul"
console.log(colores[10]); // undefined (no existe)
// Último elemento
console.log(colores[colores.length - 1]); // "azul"
console.log(colores.at(-1)); // "azul" (forma moderna)
console.log(colores.at(-2)); // "verde"
// Modificar por índice
colores[1] = 'amarillo';
console.log(colores); // ['rojo', 'amarillo', 'azul']
// length: cuántos elementos hay
console.log(colores.length); // 3Agregar y quitar elementos
| Método | Qué hace | Dónde | Devuelve |
|---|---|---|---|
push() | Agrega | Al final | Nueva longitud |
pop() | Quita | Del final | Elemento quitado |
unshift() | Agrega | Al inicio | Nueva longitud |
shift() | Quita | Del inicio | Elemento quitado |
js
const fila = ['Ana', 'Luis'];
fila.push('Sofía'); // ['Ana', 'Luis', 'Sofía']
fila.push('Diego', 'Eva'); // puedes agregar varios
const ultimo = fila.pop(); // quita 'Eva'
console.log(ultimo); // "Eva"
fila.unshift('VIP'); // ['VIP', 'Ana', 'Luis', 'Sofía', 'Diego']
const atendido = fila.shift(); // quita 'VIP'
console.log(atendido); // "VIP"
console.log(fila); // ['Ana', 'Luis', 'Sofía', 'Diego']Truco para recordarlo: push/pop trabajan al final (como una pila de platos), shift/unshift al inicio (como una fila de banco).
splice vs slice
Sus nombres se parecen mucho, pero hacen cosas muy diferentes:
slice(inicio, fin): copia una porción. No modifica el original.splice(inicio, cantidad, ...nuevos): quita, reemplaza o inserta. Sí modifica el original.
js
const meses = ['ene', 'feb', 'mar', 'abr', 'may', 'jun'];
// slice: del índice 1 al 4 (el 4 NO se incluye)
const trimestre = meses.slice(1, 4);
console.log(trimestre); // ['feb', 'mar', 'abr']
console.log(meses); // sin cambios: ['ene', 'feb', 'mar', 'abr', 'may', 'jun']
console.log(meses.slice(-2)); // ['may', 'jun'] (los últimos 2)
const copia = meses.slice(); // copia completajs
const tareas = ['Diseñar', 'Programar', 'Probar', 'Publicar'];
// splice para ELIMINAR: desde el índice 2, quita 1 elemento
const eliminadas = tareas.splice(2, 1);
console.log(eliminadas); // ['Probar']
console.log(tareas); // ['Diseñar', 'Programar', 'Publicar']
// splice para INSERTAR: en el índice 1, quita 0 y agrega 'Maquetar'
tareas.splice(1, 0, 'Maquetar');
console.log(tareas); // ['Diseñar', 'Maquetar', 'Programar', 'Publicar']
// splice para REEMPLAZAR: en el índice 3, quita 1 y pone otro
tareas.splice(3, 1, 'Desplegar');
console.log(tareas); // ['Diseñar', 'Maquetar', 'Programar', 'Desplegar']Buena práctica
Si no quieres modificar el array original, existen versiones modernas (ES2023) que devuelven un array nuevo: toSpliced(), toSorted(), toReversed() y with(indice, valor).
js
const original = ['a', 'b', 'c'];
const nuevo = original.with(1, 'B'); // ['a', 'B', 'c']
console.log(original); // ['a', 'b', 'c'] sin cambiosBuscar: includes e indexOf
js
const ingredientes = ['tortilla', 'queso', 'chile', 'queso'];
// includes: ¿existe? → true / false
console.log(ingredientes.includes('chile')); // true
console.log(ingredientes.includes('pollo')); // false
// indexOf: ¿en qué posición? → índice o -1 si no existe
console.log(ingredientes.indexOf('queso')); // 1 (la primera vez)
console.log(ingredientes.lastIndexOf('queso')); // 3 (la última vez)
console.log(ingredientes.indexOf('pollo')); // -1
// Patrón común: eliminar un elemento por su valor
const indice = ingredientes.indexOf('chile');
if (indice !== -1) {
ingredientes.splice(indice, 1);
}
console.log(ingredientes); // ['tortilla', 'queso', 'queso']Error común
Usar indexOf como condición directamente:
js
// ❌ Si 'tortilla' está en el índice 0, 0 es falsy y el if no entra
if (ingredientes.indexOf('tortilla')) { /* ... */ }
// ✅ Usa includes para preguntar "¿existe?"
if (ingredientes.includes('tortilla')) { /* ... */ }Otros métodos útiles
js
const nombres = ['Luis', 'Ana', 'Sofía'];
// join: unir en un string
console.log(nombres.join(', ')); // "Luis, Ana, Sofía"
// split (de string a array)
const etiquetas = 'html,css,js'.split(','); // ['html', 'css', 'js']
// concat o spread: unir arrays
const masNombres = ['Diego', 'Eva'];
const todos = [...nombres, ...masNombres];
// ['Luis', 'Ana', 'Sofía', 'Diego', 'Eva']
// reverse y sort (¡modifican el original!)
const numeros = [10, 1, 5, 100];
numeros.sort(); // [1, 10, 100, 5] 😵 ordena como texto
numeros.sort((a, b) => a - b); // [1, 5, 10, 100] ✅ orden numérico
// Array.isArray: ¿es un array?
console.log(Array.isArray(nombres)); // true
console.log(typeof nombres); // "object" (por eso existe isArray)Los métodos más poderosos (map, filter, find, reduce...) los verás en Métodos de arrays.
Recorrer arrays
js
const precios = [250, 180, 650];
// for...of: la forma más legible
for (const precio of precios) {
console.log(precio);
}
// for clásico: si necesitas el índice
for (let i = 0; i < precios.length; i++) {
console.log(`Producto ${i + 1}: $${precios[i]}`);
}
// forEach: ejecuta un callback por elemento
precios.forEach((precio, indice) => {
console.log(`${indice}: $${precio}`);
});Si necesitas repasar los bucles, ve a Bucles.
Arrays de objetos
Es la estructura que más usarás: así llegan los datos de una API, de una base de datos o de un archivo JSON.
js
const inventario = [
{ id: 1, nombre: 'Laptop', precio: 15999, stock: 4 },
{ id: 2, nombre: 'Mouse', precio: 299, stock: 0 },
{ id: 3, nombre: 'Teclado', precio: 899, stock: 12 },
];
// Leer una propiedad de un elemento
console.log(inventario[0].nombre); // "Laptop"
// Modificar una propiedad
inventario[1].stock = 25;
// Agregar un producto nuevo
inventario.push({ id: 4, nombre: 'Monitor', precio: 3499, stock: 7 });
// Recorrer y calcular el valor total del inventario
let valorTotal = 0;
for (const producto of inventario) {
valorTotal += producto.precio * producto.stock;
}
console.log(`Valor del inventario: $${valorTotal}`);
// Ver todo de un vistazo en la consola
console.table(inventario);Copia vs referencia
Este es uno de los conceptos más importantes (y que más bugs causa). Los arrays (y los objetos) no se copian al asignarlos: la variable guarda una referencia, es decir, la "dirección" donde vive el array.
Piénsalo como compartir el enlace de un documento de Google: si le pasas el enlace a alguien y lo edita, tú también ves los cambios, porque es el mismo documento.
js
const original = ['a', 'b', 'c'];
const otro = original; // ⚠️ NO es una copia: es el mismo array
otro.push('d');
console.log(original); // ['a', 'b', 'c', 'd'] 😱 ¡también cambió!
console.log(original === otro); // true: apuntan al mismo arrayCómo hacer una copia real
js
const original = ['a', 'b', 'c'];
// Opción 1: spread (la más usada)
const copia1 = [...original];
// Opción 2: slice
const copia2 = original.slice();
// Opción 3: Array.from
const copia3 = Array.from(original);
copia1.push('d');
console.log(original); // ['a', 'b', 'c'] ✅ sin cambios
console.log(copia1); // ['a', 'b', 'c', 'd']Copia superficial vs profunda
Las copias anteriores son superficiales: copian el array, pero si contiene objetos, esos objetos siguen siendo compartidos.
js
const carrito = [{ nombre: 'Taza', cantidad: 1 }];
const copia = [...carrito];
copia[0].cantidad = 5;
console.log(carrito[0].cantidad); // 5 😱 el objeto interno es el mismo
// ✅ Copia profunda (moderna): structuredClone
const copiaProfunda = structuredClone(carrito);
copiaProfunda[0].cantidad = 10;
console.log(carrito[0].cantidad); // 5 (no cambió)Comparar arrays
js
console.log([1, 2] === [1, 2]); // false: son dos arrays distintos en memoria
const a = [1, 2];
const b = a;
console.log(a === b); // true: misma referenciaError común
Modificar un array que recibiste como parámetro sin darte cuenta:
js
function agregarIVA(precios) {
for (let i = 0; i < precios.length; i++) {
precios[i] = precios[i] * 1.16; // ❌ modifica el array original
}
return precios;
}
// ✅ Trabaja sobre una copia (o usa map, que devuelve un array nuevo)
function agregarIVAPuro(precios) {
const resultado = [...precios];
for (let i = 0; i < resultado.length; i++) {
resultado[i] = resultado[i] * 1.16;
}
return resultado;
}Recuerda las funciones puras: no modifiques lo que recibes.
Casos de uso reales
js
// Carrito: agregar, quitar y contar
const carrito = [];
function agregar(producto) {
carrito.push(producto);
}
function quitar(id) {
const indice = carrito.findIndex((p) => p.id === id);
if (indice !== -1) carrito.splice(indice, 1);
}
agregar({ id: 1, nombre: 'Playera', precio: 250 });
agregar({ id: 2, nombre: 'Gorra', precio: 180 });
quitar(1);
console.log(`Artículos: ${carrito.length}`); // Artículos: 1
// Historial de búsquedas: máximo 5, sin repetidos, la más reciente primero
let historial = ['tenis', 'gorra'];
function registrarBusqueda(termino) {
historial = historial.filter((t) => t !== termino); // quitamos si ya estaba
historial.unshift(termino); // la ponemos al inicio
historial = historial.slice(0, 5); // máximo 5
}
registrarBusqueda('tenis');
console.log(historial); // ['tenis', 'gorra']Ejercicios
- Crea un array
pendientescon 3 tareas. Agrega una al final, una al inicio, quita la última e imprime cuántas quedan. - Dado
const letras = ['a', 'b', 'c', 'd', 'e'];, obtén['b', 'c', 'd']sin modificar el original, y luego elimina'c'del original. - Escribe
eliminarPorValor(array, valor)que devuelva un array nuevo sin la primera aparición devalor(no debe modificar el original). - Dado un array de alumnos
{ nombre, calificacion }, imprime el nombre de quienes aprobaron (calificación de 6 o más) y el promedio del grupo.
Ver solución
1.
js
const pendientes = ['Comprar dominio', 'Diseñar logo', 'Crear landing'];
pendientes.push('Configurar correo');
pendientes.unshift('Reunión con cliente');
pendientes.pop();
console.log(pendientes.length); // 42.
js
const letras = ['a', 'b', 'c', 'd', 'e'];
const parte = letras.slice(1, 4);
console.log(parte); // ['b', 'c', 'd']
const indice = letras.indexOf('c');
letras.splice(indice, 1);
console.log(letras); // ['a', 'b', 'd', 'e']3.
js
function eliminarPorValor(array, valor) {
const copia = [...array];
const indice = copia.indexOf(valor);
if (indice !== -1) copia.splice(indice, 1);
return copia;
}
const original = [1, 2, 3, 2];
console.log(eliminarPorValor(original, 2)); // [1, 3, 2]
console.log(original); // [1, 2, 3, 2]4.
js
const alumnos = [
{ nombre: 'Luis', calificacion: 8 },
{ nombre: 'Ana', calificacion: 5.5 },
{ nombre: 'Sofía', calificacion: 10 },
{ nombre: 'Diego', calificacion: 6 },
];
let suma = 0;
for (const alumno of alumnos) {
suma += alumno.calificacion;
if (alumno.calificacion >= 6) {
console.log(`✅ ${alumno.nombre}`);
}
}
const promedio = suma / alumnos.length;
console.log(`Promedio del grupo: ${promedio.toFixed(2)}`); // 7.38Resumen
- Un array es una lista ordenada; los índices empiezan en 0 y el último es
length - 1(oat(-1)). push/poptrabajan al final;unshift/shiftal inicio.slicecopia una porción sin modificar;splicequita, inserta o reemplaza modificando el original.includesresponde "¿existe?";indexOfda la posición o-1.- Recorre con
for...of,forclásico oforEach. - Los arrays de objetos son la estructura más común en proyectos reales.
- Asignar un array no lo copia: comparte la referencia. Copia con
[...array]ostructuredClonepara copias profundas.
Siguiente: Métodos de arrays