【发布时间】:2021-11-05 17:29:44
【问题描述】:
我在类的构造函数中有以下代码(为了问题而缩短):
constructor(effect: EffectInstance, names: string[], count?: number) {
this.effect = effect; // instance of a class "Effect"
let name; for (name of names) {
this.custom.set(name, this.effect); // custom: Map
}
}
EffectInstance是这个类的类型,是泛型的
当我在类的方法中更改this.effect.name 时,或者当我从映射this.custom 中获取效果并更改其名称时,两者都会更改。
据我所知,这是由于 JavaScript 对对象的引用传递行为,因为我 100% 确定我没有修改我不想修改的值。 (我希望能够重命名 custom 映射中的 Effect 实例,但保持 this.effect.name 不变)
我尝试使用 constructor() 中的参数重新实例化类,但这引发了一个新问题:我会丢失类型,而且我似乎无法弄清楚如何解决这个问题。这是我尝试过的:
(EffectInstance,供参考:<EffectInstance extends Effect>)
constructor(effect: EffectInstance, names: string[], count?: number) {
this.effect = effect;
let altEffect = effect instanceof PlayerEffect ? new PlayerEffect(effect.name, effect.ignoreRaces) : new Effect(effect.name);
let name; for (name of names) {
this.custom.set(name, altEffect);
}
}
这样做,TS 在altEffect 上引发此错误:
TS2345: Argument of type 'Effect' is not assignable to parameter of type 'EffectInstance'. 'Effect' is assignable to the constraint of type 'EffectInstance', but 'EffectInstance' could be instantiated with a different subtype of constraint 'Effect'.
我需要停止传递引用行为或保留 EffectInstance 包含的类型。我该怎么做?
【问题讨论】:
-
您无法更改按引用传递的行为 - 这是 JavaScript 工作方式不可或缺的一部分。正如您所注意到的,您传入的
effect是唯一一个同时是 this.effect 和地图中的值的实例。 -
@Joe 我不想改变行为;我正在尝试解决它或阻止它。如果措辞有误,请见谅
-
我会考虑如何将名称与效果分离,因为您想重用效果实例。您在循环中实例化的包装对象如何影响效果并允许名称覆盖?
-
@Joe 目标是让
this.effect成为保留其默认状态的效果的单独实例,而地图中的实例旨在单独修改
标签: javascript typescript pass-by-reference