TypeScript开发中如何避免subscribe赋值时初始参考数组随源数据同步变化
问题根源
数组属于JavaScript中的引用类型,你直接将data赋值给firstArray和secondArray时,两个变量实际指向同一块内存地址存储的数组数据,后续修改任意一个变量对应的数组内容,另一个会同步变化,和你写的if判断逻辑无关。
解决方法
1. 首次赋值时做深拷贝切断引用关联
不要直接赋值原始data,要拷贝出一份独立的初始数据存入secondArray,根据你的数组结构选择合适的拷贝方式:
- 若数组内仅包含数字、字符串、布尔值等基础类型,用浅拷贝即可:
// 展开运算符写法 this.secondArray = [...data] // 或者slice方法写法 this.secondArray = data.slice() - 若数组内嵌套了对象、数组等复杂类型,需要做深拷贝:
// 无特殊类型(Date、正则、函数等)时可以用JSON序列化反序列化快速实现 this.secondArray = JSON.parse(JSON.stringify(data)) // 有特殊类型时可以用项目内置的深拷贝工具方法,比如lodash的cloneDeep // this.secondArray = _.cloneDeep(data)
2. 可选:冻结初始值防止后续误修改
如果要完全避免secondArray被意外改动,可以在首次赋值后将其冻结:
// 浅冻结,仅冻结当前数组层级,嵌套结构要递归冻结 Object.freeze(this.secondArray)
修改后的完整代码示例
this.service.memberData(this.memberId).subscribe(data => { this.firstArray = data; // 仅首次初始化时赋值 if (!this.secondArray || this.secondArray.length === 0) { this.secondArray = JSON.parse(JSON.stringify(data)) Object.freeze(this.secondArray) } });
后续对比注意事项
校验两个数组是否相等时不能直接用===判断(还是会对比内存地址),可以转JSON字符串对比值:
const isChanged = JSON.stringify(this.firstArray) !== JSON.stringify(this.secondArray)
如果数组有特殊类型无法序列化,自行实现递归的数组/对象值对比逻辑即可。
内容的提问来源于stack exchange,提问作者TreyBCollier
相关产品推荐
相关产品推荐

