求助:克隆并更新对象为新实例存入数组失败,求解决方法
问题分析与解决方案
嘿,我帮你捋捋这个问题——你这是踩了浅拷贝导致引用共享的坑啦!
为啥所有元素都是最后一个值?
你用Object.assign({}, this.messageParam)做拷贝,但这只是浅拷贝:它只会复制对象的第一层属性,对于嵌套的bd对象,新拷贝出来的元素和原this.messageParam共享同一个bd引用。所以你每次循环修改this.messageParam['bd']['locale']时,其实是在修改同一个bd对象,最后数组里的所有元素自然都显示最后一次赋值的结果。
几种靠谱的解决办法
1. JSON序列化深拷贝(简单通用,适合普通对象)
如果你的messageParam里没有函数、Symbol这类特殊类型,这个方法最省事:
import { of } from 'rxjs'; // 记得导入rxjs的of public getAppPropeties(locales): Observable<any>{ const msgParms = []; locales.forEach((locale) => { // 先深拷贝出一个完全独立的新对象 const newParam = JSON.parse(JSON.stringify(this.messageParam)); // 在新对象上修改locale newParam['bd']['locale'] = String(locale); msgParms.push(newParam); // 用push比下标赋值更直观哦 }); console.log('msgParms', msgParms); return of(msgParms); // 别忘了返回Observable,原代码漏了这步 }
2. 手动逐层拷贝(可控性强,适合结构明确的对象)
如果清楚messageParam的结构,手动复制每一层属性,避免不必要的深拷贝:
import { of } from 'rxjs'; public getAppPropeties(locales): Observable<any>{ const msgParms = []; locales.forEach(locale => { const newParam = { // 拷贝外层所有属性 ...this.messageParam, // 单独拷贝bd对象,并修改locale bd: { ...this.messageParam.bd, locale: String(locale) } }; msgParms.push(newParam); }); console.log('msgParms', msgParms); return of(msgParms); }
3. 用lodash的cloneDeep(项目已用lodash时推荐)
如果你的项目里已经引入了lodash,直接用它的深拷贝方法最稳妥:
import { of } from 'rxjs'; import { cloneDeep } from 'lodash'; public getAppPropeties(locales): Observable<any>{ const msgParms = []; locales.forEach(locale => { const newParam = cloneDeep(this.messageParam); newParam['bd']['locale'] = String(locale); msgParms.push(newParam); }); console.log('msgParms', msgParms); return of(msgParms); }
额外小提醒
原代码里没有返回Observable,记得最后要返回对应的流(比如用of(msgParms)),不然调用这个方法的地方拿不到数据哦~
内容的提问来源于stack exchange,提问作者user2024080
相关产品推荐
相关产品推荐

