1

I stumbled onto a peculiarity with JavaScript, not sure if it is by design or a bug in the Chrome browser. If the base class has both a get and set property accessor with the same name, the inherited class can not override just one, it must override both.

class Class1 {
  constructor() {
    this._item = 1;
  }

  set item(value) {
    this._item = value;
  }

  get item() {
    return this._item;
  }
}

class Class2 extends Class1 {
  constructor() {
    super();
    this._item = 2;
  }

  set item(value) {
    this._item = value;
  }
}

let c1 = new Class1();
let item1 = c1.item; // item1 is 1
console.log(item1);
let c2 = new Class2();
let item2 = c2.item; // item2 should be 2, but is undefined
console.log(item2);
Barmar
  • 741,623
  • 53
  • 500
  • 612
Björn Morén
  • 693
  • 5
  • 14

1 Answers1

3

I believe this is correct.

The class prototype just has a single property named item. This property has a descriptor, which can include get and set properties, which are used as the getter and setter. If either of these properties is missing, that operation is performed normally rather than by calling the function.

Inheritance through the prototype chain is just used to find the property and its descriptor, there's no separate search for the individual properties in the descriptor. When you define the setter in Class2, that creates a new property in that prototype, with its own descriptor. This shadows the entire descriptor that would have been inherited from Class1.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Thanks @Barmar, I suspected it was something like this. Would have been convenient if it wasn't so though. There are many cases where a getter can be very simple, and only defined in the base class, and the setters are different depending how far down the inheritance chain you get. – Björn Morén Feb 22 '20 at 15:44
  • The duplicate question shows have to write a trivial getter that simply calls the superclass. – Barmar Feb 22 '20 at 15:45