0

I have an unusuall problem. What I try to achive is to modify an object's property while spreading via method. Example

const obj1 = {
    prop1: "value1",
    prop2: function() {
        this.prop1 = 10
        return "value2"
    }
}
const obj2 = {
    ...obj1,
    prop2: obj1.prop2()
}

And now, I would like obj2 to look like this:

{
    prop1: 10,
    prop2: "value2"
}

But beacause of this's scoping only prop1 in obj1 gets changed and obj2 looks like this:

{
    prop1: "value1",
    prop2: "value2"
}

I know that I could change obj1.prop1 directly afterwards, but the thing is that second part of the code (obj2 initialization) is in one of the packages my project use, and do not want to modify it. The only thing I control is the obj1 that I pass further. Is there any way to do that without modifing source code of a package?

  • 1
    fyi doing that seems to make the code hard to read – Daniel A. White Jan 27 '23 at 16:28
  • 2
    It's impossible, the spread keyword will erase keys with same name every time you can't avoid it. You'll have to do afterwards treatments (which will be more readable as @DanielA.White said) – Alex Jan 27 '23 at 16:30
  • 1
    Related: [If a variable is defined in terms of another, can it reflect changes in the binding of the other?](/q/42637782/4642212). If you use `obj.prop1` somewhere (explicitly or implicitly), then its primitive String value will be used, and there is no link between a primitive value and its origin. – Sebastian Simon Jan 27 '23 at 16:31
  • 2
    Trying to find a reason you would need to do this – epascarello Jan 27 '23 at 16:33

2 Answers2

0

You can achieve it by changing the obj2 initialization to this:

const obj2 = {
    prop2: obj1.prop2(),
    ...obj1,
    prop2: obj1.prop2(),
}

But like others mentioned in the comments - this is very smelly...

In this snippet:

const obj1 = {
    prop1: "value1",
    prop2: function() {
        this.prop1 = 10
        return "value2"
    }
}

modifying prop1 in the prop2 getter function is a side effect, and is considered to be code smell.

obe
  • 7,378
  • 5
  • 31
  • 40
0

I dont know you're use case, but maybe you could do the following. obj3 would contain your needed result

const obj1 = {
  prop1: "value1",
  prop2: function () {
    this.prop1 = 10;
    return "value2";
  }
};
const obj2 = {
  ...obj1,
  prop2: obj1.prop2()
};


const prop2 = obj1.prop2;
const prop2Value = obj1.prop2();
const obj3 = {...obj1, ...prop2, prop2: prop2Value};

console.log(obj1);
console.log(obj2);
console.log(obj3);
lchennl
  • 1
  • 2