求助:基于JavaScript类实现ToDo List的OOP代码问题
修复你的OOP风格ToDo List实现
先梳理你代码里的几个核心问题:
- 私有属性访问错误:List类里的
#toDo是私有字段,你用this.toDo访问会报错,必须用this.#toDo。 - addTask方法逻辑错误:你连续调用了两次
push,而且把push的返回值(数组新长度)传给了renderList,应该只push一次,然后把整个待办数组传过去。 - removeTask方法无效:
filter不会修改原数组,只是返回新数组,你需要用splice或者重新赋值给this.#toDo。 - Render类元素未挂载:constructor里获取的input、btn、ul都是局部变量,其他方法拿不到,得挂载到实例上。
- 渲染逻辑不完整:renderList里创建了li,但没添加到ul里,也没给删除按钮绑定事件。
- 缺失添加任务的事件绑定:Add按钮没绑定点击事件,没法触发添加操作。
下面是修正后的完整代码:
修正后的JavaScript代码
class List { #toDo = []; constructor(render) { this.render = render; // 初始化渲染空列表 this.render.renderList(this.#toDo); // 给Render类绑定删除回调 this.render.onRemoveTask = (task) => this.removeTask(task); } addTask(task) { // 只添加一次任务 this.#toDo.push(task); // 传入完整的待办数组进行渲染 this.render.renderList(this.#toDo); } removeTask(task) { // 过滤掉要删除的任务,重新赋值给私有数组 this.#toDo = this.#toDo.filter(item => item !== task); // 重新渲染列表 this.render.renderList(this.#toDo); } } class Render { constructor(container) { this.container = container; // 把DOM元素挂载到实例上,方便后续方法访问 this.inputEl = container.querySelector("input"); this.addBtn = container.querySelector("button"); this.taskUl = container.querySelector(".tasks"); // 绑定添加任务的点击事件 this.addBtn.addEventListener("click", () => this.handleAddTask()); } // 存储删除回调的方法 onRemoveTask = () => {}; // 存储添加回调的方法 onAddTask = () => {}; handleAddTask() { const taskText = this.inputEl.value.trim(); if (taskText) { // 调用List的addTask方法 this.onAddTask(taskText); // 清空输入框 this.inputEl.value = ""; } } renderList(tasks) { // 先清空现有列表,避免重复渲染 this.taskUl.innerHTML = ""; tasks.forEach(task => { const li = document.createElement("li"); li.innerHTML = `${task} <button class="delete-btn">Delete</button>`; // 给删除按钮绑定事件 const deleteBtn = li.querySelector(".delete-btn"); deleteBtn.addEventListener("click", () => this.onRemoveTask(task)); // 将li添加到ul中 this.taskUl.appendChild(li); }); } } // 初始化实例 const render = new Render(document.querySelector("#to-do-container")); const list = new List(render); // 给Render绑定添加任务的回调 render.onAddTask = (task) => list.addTask(task);
修正后的HTML代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>ToDo List</title> <style> div { margin: 80px auto; text-align: center; } input { width: 20%; } li { list-style: none; margin: 8px 0; } .delete-btn { margin-left: 10px; } </style> </head> <body> <div id="to-do-container"> <input type="text" placeholder="输入待办任务..." /> <button>Add Task</button> <ul class="tasks"></ul> </div> <script> // 把上面的JavaScript代码放在这里即可 </script> </body> </html>
关键改进说明:
- 私有字段
#toDo的正确访问方式 - 修复了addTask和removeTask的逻辑错误
- Render类中DOM元素的正确挂载与事件绑定
- 渲染时先清空列表再重新生成,避免重复内容
- 通过回调函数实现List和Render类之间的通信,解耦两个模块
内容的提问来源于stack exchange,提问作者jasper93
相关产品推荐
相关产品推荐

