Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

property getter does not reflect value of closure variable

I am confused by the way property getters interact with constructor closure.
Below is a minimal example:

function Ctor() {
  let closureX = 0
  
  Object.assign(this, {
    get publicX() { return closureX }
  })
  
  closureX++
  console.log(closureX)
}

let o = new Ctor()
console.log(o.publicX)

Why is o.publicX not changing when closureX does ?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

It is simply because that’s what Object.assign does – it does not assign getters or setters, it assigns the values associated with the keys to the other object. MDN Docs already clarifies that getters will be invoked on the source and setters will be invoked on the target:

The Object.assign() method only copies enumerable and own properties from a source object to a target object. It uses [[Get]] on the source and [[Set]] on the target, so it will invoke getters and setters. Therefore it assigns properties, versus copying or defining new properties. This may make it unsuitable for merging new properties into a prototype if the merge sources contain getters.

That last sentence is exactly what you are trying to do and it will not work.

You can verify this be checking its property descriptor and seeing that the new object did not inherit the getter from the source object, only the value that getter returns:

const object = Object.assign({}, {
    get publicX(){ return 3; }
});

console.log( object );

const definition = Object.getOwnPropertyDescriptor( object, 'publicX' )

console.log( definition ); // No getter defined, just a value

If you do want to accomplish this, the solution would probably be the old-fashioned Object.defineProperty to assign the getter:

function Ctor(){
  
  let closureX = 0;
  
  Object.defineProperty(this, 'publicX', {
      get(){ return closureX; }
  });
  
  closureX++;

}

const ctor = new Ctor();

console.log( ctor.publicX ); // It now returns the internal variable!
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading