Wolfgang Amadeus
Wolfgang Amadeus

Reputation: 396

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

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 don't 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 derived class?

Upvotes: 2

Views: 54

Answers (2)

Bergi
Bergi

Reputation: 664375

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]

Upvotes: 0

trincot
trincot

Reputation: 350147

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]

Upvotes: 1

Related Questions