Hari 22: Mini Proyek — Todo App Logic
80 min
Last updated 09 Apr 2026
Todo App — Data Layer
class TodoManager {
#todos = [];
#nextId = 1;
tambah(teks, prioritas = "normal") {
const todo = {
id: this.#nextId++,
teks: teks.trim(),
selesai: false,
prioritas,
dibuat: new Date().toISOString(),
};
this.#todos.push(todo);
return todo;
}
selesaikan(id) {
const todo = this.#todos.find(t => t.id === id);
if (!todo) throw new Error(`Todo #${id} tidak ditemukan`);
todo.selesai = !todo.selesai; // toggle
return todo;
}
hapus(id) {
const idx = this.#todos.findIndex(t => t.id === id);
if (idx === -1) throw new Error(`Todo #${id} tidak ditemukan`);
return this.#todos.splice(idx, 1)[0];
}
filter({ status, prioritas } = {}) {
return this.#todos.filter(t => {
if (status === "selesai" && !t.selesai) return false;
if (status === "aktif" && t.selesai) return false;
if (prioritas && t.prioritas !== prioritas) return false;
return true;
});
}
statistik() {
const total = this.#todos.length;
const selesai = this.#todos.filter(t => t.selesai).length;
return { total, selesai, aktif: total - selesai };
}
}
const mgr = new TodoManager();
mgr.tambah("Belajar JavaScript", "tinggi");
mgr.tambah("Buat portfolio", "tinggi");
mgr.tambah("Olahraga", "rendah");
mgr.tambah("Baca buku", "normal");
mgr.selesaikan(1);
mgr.hapus(3);
const stat = mgr.statistik();
console.log(`Total: ${stat.total}, Selesai: ${stat.selesai}, Aktif: ${stat.aktif}`);
mgr.filter({ status: "aktif" }).forEach(t =>
console.log(`[${t.prioritas}] ${t.teks}`)
);
💡
Notice: Private field (#todos) hanya bisa diakses dari dalam class. Ini adalah encapsulation yang benar di JavaScript modern.
Assignment
Implementasi TodoManager: tambah 4 todo, selesaikan 2, hapus 1, tampilkan statistik dan daftar yang aktif.
Expected output:
Total: 3, Selesai: 2
- Masak
JS
script.js
Solution
Output