41
class AbstractClass {

    constructor() {
    }

    set property(value) {
        this.property_ = value;
    }

    get property() {
        return this.property_;
    }

}

class Subclass extends AbstractClass {

    constructor() {
        super();
    }

    set property(value) {
        super.property = value;
        if (!(this.property_ instanceof SubclassAssociatedClass)) throw new TypeError();
    }

    //get property() {
    //  return super.property;
    //}

}

Override the set method of an attribute and it appears the get method must be overridden also, otherwise undefined is returned (i.e., the get method is not inherited, uncomment the subclass get property() method above and everything works fine).

I assume this is a part of the spec., it would follow though possibly if the behaviour was a consequence of cross compiling. Just to be sure, is this the correct way to code overridden setters and getters (both at the same time or not at all)?

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
user5321531
  • 3,095
  • 5
  • 23
  • 28
  • Can you edit your example so that the setter/getter is not just calling super? – Bergi Mar 09 '15 at 20:14
  • 1
    This could be helpful: http://stackoverflow.com/questions/27400010/object-prototype-definegetter-and-definesetter-polyfill/27400162#27400162. It discusses the problem in terms of `__defineGetter__` etc., but the principle is the same: if you are defining/redefining the setter on a property that already has a getter, you need to retrieve the getter and reset it along with the setter. –  Mar 10 '15 at 05:00

1 Answers1

30

Yes, this is intentional (a part of the spec). If an object has an own property (.property in your example), this property will be used and not an inherited one. If that property is existent, but is an accessor property without a getter, then undefined will be returned.

Notice that this behaviour has not changed from ES5.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Switched to CoffeeScript about the same time as ES5, prior to that `.__defineGetter__()` / setter was never going to be standardised. – user5321531 Mar 09 '15 at 21:15
  • @Bergi Out of curiosity, if you could point to the part of the spec that states this, I'd be grateful. I tried searching both the ES5 and ES6 specs but neither of them seem to explicitly state anything about overriding getters or setters. – brianpeiris Dec 14 '15 at 05:11
  • @brianpeiris: The "overriding" happens in [`[[DefineOwnProperty]]`](http://www.ecma-international.org/ecma-262/6.0/#sec-ordinary-object-internal-methods-and-internal-slots-defineownproperty-p-desc), which is called from [literal property definitions](http://www.ecma-international.org/ecma-262/6.0/#sec-method-definitions-runtime-semantics-propertydefinitionevaluation) or through [`Object.defineProperty`](http://www.ecma-international.org/ecma-262/6.0/#sec-object.defineproperty) (ES5 works basically the same, though the respective spec sections may be easier to read) – Bergi Dec 14 '15 at 18:59
  • @brianpeiris: And then when evaluating property access or assignment, [\[\[Get\]\]](http://www.ecma-international.org/ecma-262/6.0/#sec-ordinary-object-internal-methods-and-internal-slots-get-p-receiver) and [\[\[Set\]\]](http://www.ecma-international.org/ecma-262/6.0/#sec-ordinary-object-internal-methods-and-internal-slots-set-p-v-receiver) are relevant, which both use [\[\[GetOwnPoperty\]\]](http://www.ecma-international.org/ecma-262/6.0/#sec-ordinary-object-internal-methods-and-internal-slots-getownproperty-p) that doesn't care whether setter and getter or only one of them is defined. – Bergi Dec 14 '15 at 19:02
  • Is this still correct? Can you please link the spec defining it? – CSchulz Jun 21 '18 at 07:19
  • @CSchulz Yes. This hasn't changed since ES6 (linked in the above comments), you'll find the same in the current spec. – Bergi Jun 21 '18 at 09:27