◆ 継承すると this を使うより先に super の呼び出しが必要
◆ super に渡した関数の中で this を使っていて その関数を親クラスで呼び出すとエラー
◆ 親クラスでメソッド呼び出しして それを子クラスでオーバーライドしてれば問題なし
◆ class 構文使わないほうが自由度高い

JavaScript でクラスを使うとき extends を使って継承すると constructor の中で super を呼び出す必要があります
呼び出さないとエラーです
それともうひとつ制約があって呼び出したあとでしか this を使ったプロパティアクセスができません

class A { }

class B extends A {
constructor() {
this.method()
super()
}
method() {
console.log("called")
}
}

new B()
// ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor

これは this アクセスを行う関数を super に渡して super の中でそれを呼び出す場合にも影響します
super を呼び出し super の処理が終わるまでは this にアクセスできないようです

class C {
constructor(fn) {
fn()
}
}

class D extends C {
constructor() {
super(() => {this.method()})
}
method() {
console.log("called")
}
}

new D()
// ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor

しかし こういうケースは実行できてしまいます

class E {
constructor() {
this.method()
}
}

class F extends E {
constructor() {
super()
}
method() {
console.log("called")
}
}

new F()
// called

super で呼び出した E の constructor から this.method を呼び出し その実装は F にある場合です
これがいいなら C D のケースも許可してくれて良いと思うのですけどね

C D に近いやり方にしたければ プロパティの名前を引数で渡して 親クラスのコンストラクタ内で this の中の渡されたプロパティにアクセスすれば良いです

class G {
constructor(fn) {
this[fn]()
}
}

class H extends G {
constructor() {
super("method1")
}
method1() {
console.log("called")
}
}

new H()
// called

より近づけるなら少し発展させて 親クラス側からメソッド呼び出しする関数を受け取りそれを使います

class G {
constructor(fn) {
fn((methodname, ...a) => this[methodname](...a))
}
}

class H extends G {
constructor() {
super(call => {
console.log("this.s(1)+this.s(2):", call("s", 1) + call("s", 2))
})
}
s(x) {
return x * 10
}
}

new H()
// this.s(1)+this.s(2): 30

子クラスの H のコンストラクタで super に関数を渡して実行してもらう C D のやり方と同じです

複雑になってきましたがこれが必要かというとそうでもないです
本来の super 呼び出しが終わる前に this にアクセスする目的は 親クラスの初期化処理をする前になにかしておきたい もしくはコンストラクタに渡す引数を this のメソッドの返り値にしたいからだと思います

親側を自分で作れるのならこういうふうに指定のメソッド呼び出すようにしておいて子クラスでそれを実装すれば済みます

class P {
constructor(foo, bar) {
if (typeof this.beforeConstruct === "function") {
this.beforeConstruct()
}
if (typeof this.getConstructorArguments === "function") {
[foo, bar] = this.getConstructorArguments()
}
console.log(foo, bar)
}
}

とはいえこれも面倒なんですよね
しかも子クラスがそうするかどうかはわからないので そういう子クラスができるかもしれないと考えだすと全部で実装必要です
super さえ呼び出してれば先に this 呼び出してもいいようにしてくれればよかったのですけどね

これに限らず class 構文は制限がいっぱいあるので自由さを求めるなら class 構文を使わずプロトタイプベースらしい書き方をすれば解決できます

function X(v) {
console.log("[x ctor]", v, this)
}

function Y() {
this.y = 100
X.call(this, this.getValue())
}

Y.prototype.getValue = function() {
return 5
}

Y.__proto__ = X
Y.prototype.__proto__ = X.prototype

new Y()

// [x ctor] 5 Y {y: 100}

super の呼び出しに当たるのが Y 関数内の X.call です
それより前に this.y に代入したり X.call で X コンストラクタを呼び出すときの引数の取得で this.getValue を呼び出してます