Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my computed property not effective after Object.assign? [duplicate]

I stumbled upon code similar to this in modern JavaScript:

let obj = {
  data: {number: 9},
  set prop(p) {
    this.data = p;
  },
  get prop() {
    return this.data;
  }
};

obj = Object.assign({}, obj, {
  data: {number: 2}
});

console.log('obj.data === obj.prop ', obj.data === obj.prop);
console.log('obj.data.number === obj.prop.number ', obj.data.number === obj.prop.number);

Any modification is done outside of the computed property, as if there were none.

I was expecting the computed property to still exist.

Is there a way to preserve the computed property after a call to Object.assign? Thanks.

like image 959
Guillaume Racicot Avatar asked Mar 22 '19 19:03

Guillaume Racicot


1 Answers

If you look at the result of the new object created by object.assign you will see that it no longer has getter/setter, but has a property prop. object.assign doesn't copy the getter/setter functions over but instead calls [[get]] and makes a new property.

MDN describes it:

It uses [[Get]] on the source and [[Set]] on the target, so it will invoke getters and setters. Therefore it assigns properties versus just copying or defining new properties. This may make it unsuitable for merging new properties into a prototype if the merge sources contain getters.

So assign() merges an object with a prop property together with an object with a data property and you get both:

let obj = {
  data: {
    number: 9
  },

  set prop(p) {
    this.data = p;
  },

  get prop() {
    return this.data;
  }

};

obj = Object.assign({}, obj, {
  data: {
    number: 2
  }
});

// it has a data and a prop property -- they are not the same:
console.log(obj)
like image 92
Mark Avatar answered Sep 21 '22 05:09

Mark