0

JS noob here: If a getter/setter with a particular name is used that is the same as a property's name that takes on a value, and in code that is in strict mode, will an error occur in ES5? Ex (where yes, I know I am not properly using the getter and setter below in regards to their purpose):

    "use strict"; //assume is first line in script or function
    let obj = {
      p: 5,
      get p() {
        console.log("in getter");
      },
      set p(v) {
        console.log("in setter: ", v);
      }
    };

I ask here for a few reasons:

    1. I've had trouble finding a way to run pre-ES6 (namely ES5) JavaScript. (I checked here, for example, and even something like a browser may have a mix and match of ECMAScript standards.)
    1. As of ES6 duplicate property names is not an error (see here).
    1. I've played around with the order of a property and a getter and setter of the same name in ES6, and their order appears to matter. (I know that subsequently-defined properties will now be those used if of the same name, but putting a property after a getter of the same name but before a setter of the same name causes accessing that property to always evaluate to undefined, (even when yes, the getter I use is coded to return a non-undefined value, such as 6).) Ex's:
    //Ex 1:
    let obj = {
      get p() {
        console.log("in getter");
        return 6;
      },
      p: 5,
    };
    console.log(obj.p); //prints 5

    //Ex 2:
    let obj2 = {
      get p() {
        console.log("in getter");
        return 6;
      },
      p: 5,
      set p(v) {
        console.log("in setter: ", v);
      }
    };
    console.log(obj2.p); //prints undefined
mishar
  • 89
  • 6

1 Answers1

1

In JS, you cant really have a get/set and a data property with the same naming convention. They pretty much occupy the same slot on an object.

In ES5 and strict mode, if you define a data property and then define a getter/setter with the same name, or vice versa, you will overwrite the previous. This is exactly what's happening in your examples.

Here is the correct usage with use strict:

"use strict"; 
let obj = {
  _p: 5,  //use a different internal property to store the value
  get p() {
    console.log("in getter");
    return this._p;
  },
  set p(v) {
    console.log("in setter: ", v);
    this._p = v;
  }
};
console.log(obj.p);  //logs "in getter", then 5
obj.p = 10;  //logs "in setter: 10"
console.log(obj.p);  //logs "in getter", then 10

In regards to your second example, the get is defined first and then returns a const value 6. Then you define a data property p which will overwrite the get. Finally the set which will overwrite the data property. As a result, the getter is gone and trying to access obj2.p will be undefined.

jagmitg
  • 4,236
  • 7
  • 25
  • 59
  • Ok, thanks; so it seems even ES5 wouldn't throw an error then (if they were to be the same, as in my first example)? I just thought that ES5 would throw an error in the case of duplicate property names in strict-mode, which having a getter/setter and a property of the same value I also thought would trigger? – mishar Jul 23 '23 at 00:17
  • @mishar In both ES5 and ES6, defining a data property and then a get/set with the same name in the same object literal, or vice versa, will not trigger an error, even in strict mode. It just simply overwrites the former one. JS allows this, but it can be confusing and often leads to unintended behaviour, which is what you're observing. – jagmitg Jul 23 '23 at 00:21