Issue
I have the following code in the constructor of a class (shortened for the purpose of the question):
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
is the type of this class, which is generic
When I change this.effect.name
in a method of the class, or when I grab the effect from the Map this.custom
and change its name, both are changed.
From what I can tell, this is due to JavaScript's pass-by-reference behavior with objects, as I'm 100% certain that I'm not modifying the values I don't want modified. (I'd like to be able to rename the Effect instance in the custom
Map, but keep this.effect.name
unchanged)
I tried to re-instantiate the classes with the parameters in constructor()
, but this raises a new issue: I'd be losing types, and I can't seem to figure out how to work around this. Here's what I tried:
(EffectInstance
, for reference: <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);
}
}
Doing so, TS raises this error on 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'.
I need to either stop the pass-by-reference behavior or preserve the type that EffectInstance contains. How can I do this?
Solution
Most languages pass objects by reference, so this is not a unique behavior with javascript.
If you want to pass a copy of the class instance and not the original instance and send the clone where you don't want send the original instance.
class Car {
constructor(name) {
this.name = name;
}
}
let orignalClass = new Car('BMW');
let cloneClass = Object.assign(Object.create(Object.getPrototypeOf(orignalClass)), orignalClass)
console.log(orignalClass);
console.log(cloneClass);
// now both can be updated individually
orignalClass.name = 'BMw-1';
cloneClass.name = "BMW-copy"
console.log("after update");
console.log(orignalClass);
console.log(cloneClass);
Answered By - vaira Answer Checked By - Senaida (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.