从LocalStorage恢复后,对象数组中Task方法消失的问题
问题描述
将包含多层对象的结构存储在LocalStorage中,由于序列化会导致对象丢失方法,取回时尝试通过Object.assign将存储的数据与对应类的新实例合并以恢复方法,但出现异常:Task类的taskHTML方法在单独查看Task对象时存在,将其存入Project的tasks数组后,展开Project对象查看tasks数组时该方法消失。
相关代码如下:
const newMasterObject = new cls.masterObject() const storedMasterObject = JSON.parse(localStorage.masterObject) // 迁移所有项目和任务 newMasterObject.projects = storedMasterObject.projects.map(project=>{ const newProject = new cls.Project() const newTasks = project.tasks.map(task=>{ const variable= Object.assign(new cls.task(),task); return variable }); console.log(newTasks) newProject.tasks = newTasks console.log(newProject.tasks) console.log(newProject) return Object.assign(newProject, project) })
调试发现:单独打印newTasks和newProject.tasks时,其中的Task对象均存在taskHTML方法;但展开打印的newProject对象查看tasks数组时,该方法消失。
问题原因与解决办法
原因
最后一步Object.assign(newProject, project)会将存储的原始project对象中的tasks数组直接覆盖掉你刚创建的、带有taskHTML方法的tasks数组。因为从LocalStorage取出的project里的tasks是序列化后的纯数据对象数组,没有任何类方法,所以覆盖后newProject.tasks就变回了无方法的版本。
解决办法
调整逻辑,避免存储的project对象中的tasks字段覆盖已处理好的带方法的tasks数组,有两种实现方式:
方式1:合并时排除tasks字段
先将project中的非tasks数据合并到新实例,再赋值处理好的tasks数组:
const newMasterObject = new cls.masterObject() const storedMasterObject = JSON.parse(localStorage.masterObject) newMasterObject.projects = storedMasterObject.projects.map(project=>{ const newProject = new cls.Project() // 解构project,剔除tasks字段,只保留其他数据 const { tasks: _, ...projectData } = project // 合并非tasks数据到新实例 Object.assign(newProject, projectData) // 处理tasks并赋值 const newTasks = project.tasks.map(task=>{ return Object.assign(new cls.task(), task); }); newProject.tasks = newTasks console.log(newTasks) console.log(newProject.tasks) console.log(newProject) return newProject })
方式2:调整赋值与合并的顺序(需确保project无tasks字段覆盖风险)
先给newProject赋值带方法的tasks数组,再合并project的其他数据(若project中包含tasks字段,仍会覆盖,因此更推荐方式1):
const newMasterObject = new cls.masterObject() const storedMasterObject = JSON.parse(localStorage.masterObject) newMasterObject.projects = storedMasterObject.projects.map(project=>{ const newProject = new cls.Project() const newTasks = project.tasks.map(task=>{ return Object.assign(new cls.task(), task); }); // 先赋值处理好的tasks newProject.tasks = newTasks // 合并project的其他数据(注意:若project含tasks字段,会覆盖新赋值的tasks) Object.assign(newProject, project) console.log(newTasks) console.log(newProject.tasks) console.log(newProject) return newProject })
内容的提问来源于stack exchange,提问作者Hungry_munk
相关产品推荐
相关产品推荐

