PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Tuesday, July 5, 2022

[FIXED] How can I stop JavaScript from passing a class by reference?

 July 05, 2022     javascript, pass-by-reference, typescript     No comments   

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)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing