JavaScript: duplicate property name and getter/setter an error in ES5?

106 Views Asked by At

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
1

There are 1 best solutions below

2
jagmitg On BEST ANSWER

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.