Lección 20 · 20 de 20
Proyecto: lista de tareas · JavaScript
Un pequeño proyecto en JavaScript que lo reúne todo: una lista de tareas con órdenes de texto, objetos, arrays, funciones, errores y JSON.

Este programa junta lo visto en el curso en una lista de tareas que se maneja con órdenes de texto: add añade una tarea, done la marca como hecha y remove la quita. Las órdenes están en el array commands, como si alguien las hubiera tecleado.
Cada tarea es un objeto con id, title y done, y todas se guardan en el array tasks. nextId es un let porque aumenta con cada tarea nueva; nextId++ devuelve el valor actual y después le suma 1.
La función run interpreta una orden. Con desestructuración y rest, const [command, ...words] = line.split(" ") separa la primera palabra del resto, y join vuelve a unir el título. Para done y remove, find busca la tarea por su número y splice la quita del array.
Cuando algo no cuadra, run lanza un error con throw: la tarea 7 no existe y jump no es una orden conocida. El bucle principal llama a run dentro de un try/catch, así que cada error se muestra y el programa sigue con la orden siguiente.
Al final se escribe la lista con [x] o [ ] según done (un ternario), padStart alinea los números, filter cuenta las pendientes y JSON.stringify la prepara para guardarla. Es el mismo JavaScript con el que se programan las aplicaciones Electron, React, Next.js y React Native de DMarlon Studio.
Código · main.js
// A small to-do list driven by text commands.const commands = ["add Buy milk", "add Call the dentist", "add Water the plants", "done 1", "remove 2", "done 7", "add Finish the JavaScript course", "jump 3"];const tasks = [];let nextId = 1;function run(line) { const [command, ...words] = line.split(" "); const text = words.join(" "); if (command === "add") { tasks.push({ id: nextId, title: text, done: false }); return `added #${nextId++} "${text}"`; } const task = tasks.find((t) => t.id === Number(text)); if (!task) throw new Error(`there is no task #${text}`); if (command === "done") task.done = true; else if (command === "remove") tasks.splice(tasks.indexOf(task), 1); else throw new Error(`unknown command "${command}"`); return `${command} #${task.id}`;}for (const line of commands) { try { console.log("ok ", run(line)); } catch (error) { console.log("error", error.message); }}for (const { id, title, done } of tasks) { console.log(`${done ? "[x]" : "[ ]"} ${String(id).padStart(2)} ${title}`);}const pending = tasks.filter((t) => !t.done).length;console.log(`${tasks.length} tasks, ${pending} pending`);console.log("Saved as JSON:", JSON.stringify(tasks).length, "characters");Salida · node main.js
ok added #1 "Buy milk" ok added #2 "Call the dentist" ok added #3 "Water the plants" ok done #1 ok remove #2 error there is no task #7 ok added #4 "Finish the JavaScript course" error unknown command "jump" [x] 1 Buy milk [ ] 3 Water the plants [ ] 4 Finish the JavaScript course 3 tasks, 2 pending Saved as JSON: 151 characters
Para recordar
- Los datos: un array de objetos, uno por tarea.
- Una función por tarea concreta: aquí,
runinterpreta cada orden. throwpara los errores ytry/catchpara que el programa continúe.find,filter,splice, plantillas y JSON trabajan juntos.
Ejercicio
Añada la orden rename 3 Nuevo título, que cambie el título de una tarea, y la orden clear, que quite todas las tareas hechas con filter.