通过对象实例化PaymentCoordinator类时categories属性无法设置问题
问题原因与解决方案
核心原因
你遇到的问题本质是TypeScript私有属性的特性导致的:
当你在构造函数参数前添加private修饰符时,TypeScript会自动将这些参数转换为类的私有实例字段(编译为ES标准的私有字段#categories,或旧版中不可枚举的命名空间属性)。这类私有属性有两个关键特性:
Object.assign无法复制私有字段,因为它只会处理对象的可枚举自有属性,而私有字段不可枚举且外部无法直接访问;- 若
obj是普通对象(而非PaymentCoordinator类实例),直接赋值this.categories = obj.categories时,实际是在实例上新增了一个普通的categories属性,但TypeScript会优先让你访问类的私有字段#categories,导致你看起来赋值没生效。
另外,你的构造函数参数顺序也有问题:前面的categories参数没有默认值,当你调用构造函数进行克隆时,必须传入该参数(哪怕是undefined),这会先初始化私有字段为传入的值,后续的赋值操作可能被覆盖或无法正确映射到私有字段上。
解决方法
方法1:手动克隆所有私有属性(推荐)
放弃依赖Object.assign,手动复制每个属性,确保私有字段能正确被赋值,同时还能避免数组的引用问题:
constructor( private amount: number, private description: string, private title: string, private transactionType: string, private creditors: Array<any>, private categories: Array<string>, private startdate: Date = undefined, private enddate: Date = undefined, obj: any = false ) { if (obj) { // 手动覆盖所有属性,确保私有字段被正确赋值 this.amount = obj.amount; this.description = obj.description; this.title = obj.title; this.transactionType = obj.transactionType; this.creditors = [...obj.creditors]; // 浅拷贝数组,避免引用共享 this.categories = [...obj.categories]; // 同理处理categories this.startdate = obj.startdate ? new Date(obj.startdate) : undefined; this.enddate = obj.enddate ? new Date(obj.enddate) : undefined; } }
方法2:调整构造函数逻辑顺序
将克隆逻辑放在参数初始化之前,确保私有字段被克隆值覆盖:
constructor( obj: any = false, private amount: number = 0, private description: string = '', private title: string = '', private transactionType: string = '', private creditors: Array<any> = [], private categories: Array<string> = [], private startdate: Date = undefined, private enddate: Date = undefined ) { if (obj) { // 先处理克隆,覆盖默认参数初始化的值 Object.assign(this, obj); // 单独处理数组,避免引用问题 this.categories = obj.categories ? [...obj.categories] : []; } }
方法3:弱化属性访问限制
如果不需要严格的私有访问控制,可以将private修饰符改为protected,或者直接去掉,让属性成为普通可枚举属性,这样Object.assign就能正常复制所有属性:
constructor( amount: number, description: string, title: string, transactionType: string, creditors: Array<any>, categories: Array<string>, startdate: Date = undefined, enddate: Date = undefined, obj: any = false ) { // 手动将参数挂载为实例属性 this.amount = amount; this.description = description; this.title = title; this.transactionType = transactionType; this.creditors = creditors; this.categories = categories; this.startdate = startdate; this.enddate = enddate; if (obj) { Object.assign(this, obj); } }
内容的提问来源于stack exchange,提问作者tobstar
相关产品推荐
相关产品推荐

