【问题标题】:How can I call a superclass method like it was defined on the derived class?如何调用派生类上定义的超类方法?
【发布时间】:2022-10-25 09:08:38
【问题描述】:

我有这些课程:

class Control {
  get code() {
    return 3;
  }
  getCodeChain() {
    var result = [this.code];
    if (super.getCodeChain) {
      result = result.concat(super.getCodeChain());
    }
    return result;
  }
}

class SubControl extends Control {
  get code() {
    return 2;
  }
}

class AnotherControl extends SubControl {
  get code() {
    return 1;
  }
}

console.log((new AnotherControl()).getCodeChain()); // prints 1

当我在 AnotherControl 实例上调用 getCodeChain 时,它一直到 Control 上下文,因此递归忽略 AnotherControl 和 SubControl 上下文。

我需要得到CodeChain,但我不想/不能在所有子类中实现getCodeChain() 方法。我期望的结果是[1,2,3]。

如何调用派生类上定义的超类方法?

【问题讨论】:

  • 在子类中定义getCodeChain() 并不能解决问题。你会得到[1, 1, 1],因为它仍然会调用实际类的getter。

标签: javascript class extends superclass


【解决方案1】:

您可以使用Object.getPrototypeOf 跟踪原型链:

class Control {
    get code() { return 3; }
    getCodeChain() {
        const result = [];
        for (let proto = Object.getPrototypeOf(this); Object.hasOwn(proto, "code"); proto = Object.getPrototypeOf(proto)) {
            result.push(proto.code);
        }
        return result;
    }
}

class SubControl extends Control {
    get code() { return 2; }
}

class AnotherControl extends SubControl {
    get code() { return 1; }
}

console.log((new AnotherControl()).getCodeChain()); // [1, 2, 3]

【讨论】:

  • 所以,不要使用super
  • 确实,没有使用super。见documentation on mdnsuper 的引用由声明的类或对象文字 super 确定,而不是调用该方法的对象”
  • 这个答案是正确的。唯一的观察是,如果子类没有“代码”属性但上面的超类有,它会停止链。因此,停止条件必须是 hasOwn(proto, "getCodeChain")。
  • @WolfgangAmadeus,我明白你在做什么,但是你不能得到一个像提问者正在寻找的数组,所以我们必须假设code 在链的每一步都定义了。其次,该提议的停止条件仍然需要包含(不排除)最后一步。
【解决方案2】:

super 关键字仅在被覆盖的方法中有效。即使这样,它也会调用当前实例 (this) 上的超级方法,因此访问其他属性 (.code) 将再次解决子类上的问题。

你真正想要的更像

class Control {
  get codeChain() {
    return [3];
  }
}

class SubControl extends Control {
  get codeChain() {
    return [2, ...super.codeChain];
  }
}

class AnotherControl extends SubControl {
  get codeChain() {
    return [1, ...super.codeChain];
  }
}

console.log((new AnotherControl()).codeChain); // prints [1, 2, 3]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    • 2012-05-31
    • 2014-01-27
    • 2021-10-09
    • 1970-01-01
    • 1970-01-01
    • 2016-01-01
    相关资源
    最近更新 更多