覆盖一个setter,getter也必须被覆盖。

43
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;
    //}

}

如果重写属性的set方法,则似乎还必须重写get方法,否则会返回undefined(即未继承get方法),请取消注释上面的子类get property()方法,一切都能正常工作。

我假设这是规范的一部分, 如果这种行为是跨编译的结果,那么可能会遵循。只是为了确保,这是编写覆盖setter和getter方法(同时或者完全不)的正确方式吗?


你能否编辑你的示例,使得setter/getter不仅仅是调用super? - Bergi
1
这个链接可能会有所帮助:http://stackoverflow.com/questions/27400010/object-prototype-definegetter-and-definesetter-polyfill/27400162#27400162。它讨论了`__defineGetter__`等问题,但原则是相同的:如果您正在定义/重新定义已经具有getter的属性的setter,则需要检索getter并在重置setter时将其一起重置。 - user663031
1个回答

32
是的,这是故意的(规范的一部分)。如果一个对象有自己的属性(在您的示例中为 .property),则将使用该属性而不是继承的属性。如果该属性存在,但是是一个没有 getter 的访问器属性,则会返回 undefined
请注意,这种行为与 ES5 没有变化。

在 ES5 左右的时间,我转向使用 CoffeeScript。在那之前,.__defineGetter__() / setter 永远不会被标准化。 - user5321531
@Bergi 出于好奇,如果您能指出规范中说明这一点的部分,我将不胜感激。我尝试搜索了ES5和ES6规范,但它们似乎都没有明确说明关于覆盖getter或setter的任何内容。 - brianpeiris
@brianpeiris: "覆盖"事件发生在[[DefineOwnProperty]]中,该事件可通过字面属性定义或者通过Object.defineProperty调用(ES5基本上相同,尽管各自的规范部分可能更容易阅读)。 - Bergi
@brianpeiris:然后在评估属性访问或赋值时,[[Get]][[Set]]是相关的,它们都使用[[GetOwnPoperty]],该方法不关心是否定义了setter和getter或只有其中一个。 - Bergi
这还正确吗?请问你能给我指定规范的链接吗? - CSchulz
@CSchulz 是的。自ES6(在上面的评论中链接)以来,这一点并没有改变,您会在当前规范中找到相同的内容。 - Bergi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接