JavaScript对象深度赋值异常:数组元素批量被修改原因咨询
问题原因分析与解决办法
问题根因:浅拷贝导致的引用共享
你创建对象时使用的Object.assign({}, obj)是浅拷贝,它只会复制对象的第一层属性值:
- 若属性是字符串、数字、布尔这类基本类型,会复制具体的值,所以每个对象的
Text是独立的,修改一个不会影响其他,这也是前两个赋值操作能正常工作的原因。 - 若属性是对象、数组这类引用类型,
Object.assign只会复制引用地址——也就是说,多个对象会共享同一个底层引用对象。
拿你的对象创建流程拆解:
Object4里的ObjectA是Object.assign({}, Object5),这一步没问题,因为Object5是单层基本类型属性,拷贝的是具体值。- 创建
Object3的数组时,[Object.assign({}, Object4), Object.assign({}, Object4)]生成的两个新对象,它们的ObjectA属性其实都指向同一个Object5的拷贝对象(Object.assign拷贝Object4时,只是把Object4.ObjectA的引用复制了过去)。 - 后续
Object2、Object1的数组创建都用了同样的浅拷贝逻辑,导致所有层级里的ObjectA(即Object4中的那个ObjectA)最终都共享同一个底层对象。
所以当你执行_SetObjectByName(Object1,'ObjectA[0].ObjectA[0].ObjectA[0].ObjectA.Number1',1)时,修改的是这个共享对象的Number1属性,所有引用它的数组元素自然都会同步变化。
解决办法:改用深拷贝
把所有创建对象时的Object.assign({}, obj)替换为深拷贝,确保每个层级的对象都是独立的。常见的深拷贝方式有两种:
方法1:JSON序列化/反序列化(适合无特殊类型的对象)
这种方式简单快捷,但不支持函数、Symbol、循环引用等特殊类型:
// 替换原来的Object.assign为JSON.parse(JSON.stringify(obj)) let Object4 = { Text: '', ObjectA: JSON.parse(JSON.stringify(Object5)), ObjectB: JSON.parse(JSON.stringify(Object5)), ObjectC: JSON.parse(JSON.stringify(Object5)), ObjectD: JSON.parse(JSON.stringify(Object5)), }; let Object3 = { Text: '', ObjectA: [ JSON.parse(JSON.stringify(Object4)), JSON.parse(JSON.stringify(Object4)) ] }; // 同理修改Object2、Object1的创建代码
方法2:手写递归深拷贝函数
如果需要支持特殊类型,可以自己实现递归深拷贝:
function deepClone(obj) { if (obj === null || typeof obj !== 'object') return obj; if (obj instanceof Array) { return obj.map(item => deepClone(item)); } const clonedObj = {}; for (let key in obj) { if (obj.hasOwnProperty(key)) { clonedObj[key] = deepClone(obj[key]); } } return clonedObj; } // 创建对象时用deepClone替换Object.assign let Object4 = { Text: '', ObjectA: deepClone(Object5), ObjectB: deepClone(Object5), ObjectC: deepClone(Object5), ObjectD: deepClone(Object5), };
内容的提问来源于stack exchange,提问作者noname028743
相关产品推荐
相关产品推荐

