原生JavaScript Todo项目:如何实现对象数组的可变与不可变更新?
原生JS Todo项目:对象数组的可变/不可变动态更新方法
我正在用原生JavaScript开发Todo项目,需要编写updateProject函数来更新项目的标题、描述、优先级等信息,想了解如何对对象数组进行可变或不可变的动态更新。现有代码如下:
// 示例:直接修改任务标题 project1.tasks[2].title = newTitle
// Project Manager 对象 const PM = { // 空项目数组 projects: [], // 添加项目到数组的方法 addProject(project) { this.projects.push(project) }, deleteProject(project) { const projectIndex = this.projects.indexOf(project) if (projectIndex !== -1) { this.projects.splice(projectIndex, 1) return true } return false }, updateProject() { // 待实现:更新项目标题、描述、优先级 } }
const projectFactory = (title) => ({ title, tasks: [], addTask(task) { this.tasks.push(task) }, deleteTask(task) { const taskIndex = this.tasks.indexOf(task) if (taskIndex !== -1) { this.tasks.splice(taskIndex, 1) return true } return false } })
const createProject = (title) => { const project = projectFactory(title) return project }
const taskFactory = (title, description, dueDate, priority) => ({ title, description, dueDate, priority }) const createTask = (title, description, dueDate, priority) => { const task = taskFactory(title, description, dueDate, priority) return task }
const project1 = projectFactory("Clean") const task1 = taskFactory("Clean kitchen", "Wash dishes", "1/19/2023", "Medium") PM.addProject(project1) project1.addTask(task1)
我参考过StackOverflow的类似问题,但它们要么用ID,要么基于React实现,不符合我的需求。
一、可变更新方案(直接修改原对象)
这种方式直接修改原项目/任务对象,无需创建新实例,适合不需要追踪数据变更历史的场景。
1. 实现PM的updateProject方法
传入目标项目和要更新的属性,直接覆盖原对象的对应值:
updateProject(targetProject, updates) { const projectIndex = this.projects.indexOf(targetProject) if (projectIndex === -1) return false // 遍历更新属性,直接修改原对象 Object.assign(this.projects[projectIndex], updates) return true }
使用示例:
// 更新project1的标题并添加优先级属性 PM.updateProject(project1, { title: "Deep Clean", priority: "High" })
2. 动态更新任务
和示例逻辑一致,直接通过数组索引修改任务属性,支持批量更新:
// 修改project1中第3个任务的标题 project1.tasks[2].title = "Mop kitchen floor" // 批量更新任务的描述和优先级 Object.assign(project1.tasks[2], { description: "Mop all areas and clean baseboards", priority: "High" })
二、不可变更新方案(返回新数据,不修改原对象)
这种方式会创建新的数组或对象副本,原数据保持不变,适合需要追踪数据变化、实现撤销/重做功能的场景。
1. 实现不可变的updateProject方法
updateProject(targetProject, updates) { const projectIndex = this.projects.indexOf(targetProject) if (projectIndex === -1) return this.projects // 返回原数组 // 创建新数组,替换目标项目为更新后的副本 return [ ...this.projects.slice(0, projectIndex), { ...targetProject, ...updates }, ...this.projects.slice(projectIndex + 1) ] }
使用示例:
// 更新后得到新的projects数组,原PM.projects不受影响 const updatedProjects = PM.updateProject(project1, { title: "Deep Clean", priority: "High" }) // 如需替换原数组,手动赋值 PM.projects = updatedProjects
2. 不可变更新任务
// 创建新的项目对象,修改指定任务的属性,原project1保持不变 const updatedProject = { ...project1, tasks: [ ...project1.tasks.slice(0, 2), { ...project1.tasks[2], title: "Mop kitchen floor" }, ...project1.tasks.slice(3) ] }
内容的提问来源于stack exchange,提问作者DataMoshing
相关产品推荐
相关产品推荐

