JavaScript中重新赋值的变量被突变的原因与解决方案
原因说明及解决方案
核心原因
JavaScript中对象属于引用类型,let newPage = page 仅复制了对象的内存引用地址,两个变量指向堆内存中的同一份数据,因此修改newPage的深层属性时,原page对象会同步被修改。
拷贝方案
你使用的obj = JSON.parse(JSON.stringify(o)) 是普通场景下可用的深拷贝实现,仅需注意该方案存在以下限制:
- 无法保留函数、Symbol、undefined类型的属性
- 遇到对象循环引用会抛出错误
- 会自动将Date对象转为字符串、RegExp对象转为空对象
如果你的数据中存在以上特殊类型,可以使用以下方案:
- 层级较浅的对象可以手动逐层展开拷贝,做到最小粒度的不可变更新:
// 示例:逐层拷贝需要修改的属性层级 const newPage = { ...page, components: page.components.map(component => { if (component.blocks) { return { ...component, blocks: component.blocks.map(block => { if (block.type !== 'checklist') return block // 仅拷贝需要修改的checklist类型block const newBlock = { ...block, id: uuidv4(), data: Object.fromEntries( Object.entries(block.data).map(([key, item]) => [key, {...item, id: uuidv4()}]) ) } return newBlock }) } } return component }) }
- 现代浏览器、Node.js运行环境可以直接使用原生结构化克隆API:
const newPage = structuredClone(page)
内容的提问来源于stack exchange,提问作者PurplePineapple
相关产品推荐
相关产品推荐

