0

If I want to define a constant in base class, then override it in sub-classes, how should I do?

The catch is that, for my specific case, this constant is a new Map(), and the result will be consulted with during constructor:

class Cmd0 {
  constructor(name, arg1, arg2 = null) {
    this.name = name;
    this.arg1 = arg1;
    this.arg2 = arg2;
  }
. . .
}

class Cmd extends Cmd0 {
  constructor(name, arg1, arg2 = null) {
    myMap =  Somehow.getMyMap() // defined in sub-classes
    if (!myMap.has(name)) { super(null, null, null); return } // fail the constructor
    super(name, arg1, arg2)
  }
}

class SubCmd1 extends Cmd {

  Usage() {
    if (this.name) return null
    else return "cmd sub1 bla bla bla"
  }
}

class SubCmd2 extends Cmd {

  Usage() {
    if (this.name) return null
    else return "cmd sub2 bla bla bla"
  }
}

Both SubCmd1 and SubCmd2 need to define their own version of getMyMap() to be consumed in base constructor, before this can be accessed.

The getMyMap() method would be in the format of,

getMyMap() {
  return new Map()
    .set("name1", arg11, arg12)
    .set("name2", arg21, arg22)
}

Is it possible to somehow make it work? You can start from - https://jsbin.com/xubijosuro/edit?js,console,output

PS. Here is how I'm using SubCmd1, SubCmd2, etc:

const cli = new CliCaseA(name, argsObj) 
const usage = cli.Usage() 
if (usage) { console.log(`Usage:\n\n${usage}`) process.exit() }
xpt
  • 20,363
  • 37
  • 127
  • 216
  • Can you post an example of the `getMyMap` methods, so we can see what they depend on? – CertainPerformance Feb 09 '19 at 21:14
  • @CertainPerformance, updated. Basically I wanted to define `getMyMap` methods as `static`, but don't know how to access them in base class. – xpt Feb 09 '19 at 21:18

1 Answers1

2

You are looking for a static property of the class (or getter or method) that you can access even before the super() call using new.target:

class MappedCmd extends Cmd {
  constructor(name, arg1, arg2 = null) {
    const myMap = new.target.getMyMap();
//                ^^^^^^^^^^
    …
    super(name, arg1, arg2)
  }
  static getMyMap() {
    return new Map(); // to be overridden or extended in the subclasses
  }
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thanks Bergi. Can the constructor you provided be moved from `SubCmdX` level to `Cmd` level, as all of them will otherwise using the exact same code? Also, do you know if there is any site that I can try out the above ES6 code? I tried https://jsbin.com/xubijosuro/edit?js,console,output, but got _"TypeError: .new.target.getMyMap is not a function"_. Is there any place that you can demonstrate that the ES6 code is working (_without transpiling_)? – xpt Feb 10 '19 at 03:07
  • If I turn `getMyMap()` into `static`, as in https://jsbin.com/fihiqayuki/1/edit?js,console,output, then I'll get "_ReferenceError: myMap is not defined_" instead. – xpt Feb 10 '19 at 03:13
  • The code in your jsbin is missing the `static` and `const` keywords. – Bergi Feb 11 '19 at 13:37