TypeScript中如何更新类对象属性?遇对象不可扩展错误
问题解决:无法修改对象属性,提示"object is not extensible"
问题场景
现有类定义consumption.ts:
export class ConsumptionDetails { Id: string; Status: string; Description: string; Quantity: number; }
在组件的Function 1中订阅数据:
this.lineItems$.subscribe((result: BindingState<ConsumptionDetails>) => { if(result){ this.tempObj = result; } });
在Function 2中尝试修改属性时报错:
this.tempObj.Status = 'Submitted'; console.log(this.tempObj);
错误信息:
ERROR TypeError: Cannot add property Status, object is not extensible
原因分析
BindingState<ConsumptionDetails>返回的对象是不可扩展/被冻结的,这类对象通常由状态管理库(如NgRx)或框架内部处理生成,目的是保证数据不可变,避免意外修改原始状态。这类对象通过Object.preventExtensions()、Object.seal()或Object.freeze()被限制了扩展能力,直接修改属性会触发报错。
解决方案
1. 浅拷贝生成可扩展对象
在Function 1中,将返回的结果浅拷贝到新对象中,新对象默认是可扩展的:
this.lineItems$.subscribe((result: BindingState<ConsumptionDetails>) => { if(result){ // 使用对象展开运算符浅拷贝 this.tempObj = {...result}; // 或者用Object.assign实现 // this.tempObj = Object.assign({}, result); } });
之后再执行this.tempObj.Status = 'Submitted'就可以正常修改属性了。
2. 转换为类实例(如果需要保留类的结构)
如果需要tempObj是ConsumptionDetails的实例,可以用Object.assign将结果赋值给类的新实例:
this.lineItems$.subscribe((result: BindingState<ConsumptionDetails>) => { if(result){ this.tempObj = Object.assign(new ConsumptionDetails(), result); } });
3. 深拷贝(针对有嵌套属性的场景)
如果result包含嵌套对象,浅拷贝无法处理嵌套层级的不可扩展问题,这时可以用深拷贝:
this.lineItems$.subscribe((result: BindingState<ConsumptionDetails>) => { if(result){ // 用JSON序列化/反序列化实现深拷贝(注意:会丢失函数、Symbol等特殊类型) this.tempObj = JSON.parse(JSON.stringify(result)); // 或者使用lodash的cloneDeep(需先安装lodash) // import { cloneDeep } from 'lodash'; // this.tempObj = cloneDeep(result); } });
内容的提问来源于stack exchange,提问作者tamilselvan s
相关产品推荐
相关产品推荐

