Home > Mobile >  JavaScript: How can I call a superclass method like it was defined on the derivated class?
JavaScript: How can I call a superclass method like it was defined on the derivated class?

Time:10-10

I have these classes:

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

When I call getCodeChain on AnotherControl instance, it goes all the way up to Control context, so the recursion ignores AnotherControl and SubControl contexts.

I need to get the CodeChain, but I dont want/can implement the getCodeChain() method in all subclasses. The results I expect is [1,2,3].

How can I call a superclass method like it was defined on the derivated class?

CodePudding user response:

You can follow the prototype chain using 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]

CodePudding user response:

The super keyword works only in the overridden method. And even then, it calls the super method on the current instance (this), so accessing an other property (.code) will again resolve that on the subclass.

What you really want is more like

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]

  • Related