TL;DR
タイトルのままです。
背景:よく出会うエラー
SyntaxError: missing super() call in constructor
SyntaxError: 'this' is not allowed before super()
SyntaxError: 'super.*' is not allowed before super()
1. 子クラスのconstructor()
ではsuper()
呼び出しが必須
エラーになるコード例
こういうコードはエラーになります。
class Parent {
}
class Child extends Parent {
constructor() {}
}
解決・解消コード例
super()
を追加します。
class Parent {
}
class Child extends Parent {
constructor() { super(); }
}
または特にコンストラクタで何もしないなら、constructor()
自体を削除してしまいましょう。
class Parent {
}
class Child extends Parent {
}
これは、デフォルトで以下のように書いたのと同じです。
class Child extends Parent {
constructor(...args) { super(...args); }
}
ちなみにこのコードは、new Child()
したときの引数をそのまま親クラスのコンストラクタへ引数として渡します。
2. 子クラスのconstructor()
ではsuper()
の前でthis
を参照することはできない
エラーになるコード例
こういうコードは、どの子クラス定義でもエラーになります。
class Parent {}
class Child01 extends Parent {
constructor(params) {
// super()の前で自プロパティへ代入
this.params = params;
super();
}
}
class Child02 extends Parent {
constructor(params) {
// super()の前で自クラスのメソッドを呼ぶ
const processed_params = this.preprocessing(params);
super(processed_params);
}
preprocessing(params) {
// process something
}
}
解決・解消コード例
基本的にはsuper()
呼び出しより後にthis.*
を移動させると良いでしょう。
class Child01 extends Parent {
constructor(params) {
super();
this.params = params;
}
}
Child02
クラスのように、自クラスのメソッドの結果をsuper()
に渡している場合は前後入れ換えで解決しませんが、このようなケースではクラス設計に間違いがある場合がほとんどです。
class Child02 extends Parent {
constructor(params) {
super(params);
this.preprocessing();
}
}
上記のように引数をそのまま渡してsuper()
を呼び、その後に自インスタンスを加工するという順番にできないか検討してみましょう。
ちなみに、super()
の戻り値と、super()
の後で参照できるthis
は同じものです。
class Parent {}
class Child02 extends Parent {
constructor() {
const instance = super();
console.log(instance === this); // => true
}
}
new Child02();
3. 子クラスのconstructor()
ではsuper()
の前でsuper.*
(親クラス呼び出し)はできない
エラーになるコード例
こういうコードは、どの子クラス定義でもエラーになります。
class Parent {
processing(params) {
// process something
}
get name() { return 'NAME'; }
}
class Child01 extends Parent {
constructor(params) {
// 親クラスのプロパティを参照する
const name = super.name + params;
super();
}
}
class Child02 extends Parent {
constructor(params) {
// 親クラスのメソッドを呼ぶ
const processed_params = super.processing(params);
super(processed_params);
}
}
解決・解消コード例
これらもthis
のときと同様、基本的にはsuper()
を先に呼ぶようにします。
class Child01 extends Parent {
constructor(params) {
super();
const name = super.name + params;
}
}
Child02
のように親クラスのメソッドの実行結果をsuper()
の引数として渡している場合は、this
のときと同じようにクラス設計を見直して、親クラスのconstructor()
の方にprocessing()
実行を移動させてしまうのが良いでしょう。
class Parent {
constructor(params) {
this.processed_params = this.processing(params);
}
processing(params) {
// process something
}
}
class Child02 extends Parent {
constructor(params) {
super(params);
this.processed_params
}
}
以上です。役に立ちそうでしたら「ストック」してもらえると嬉しいです。
それでは、良いES6ライフをお過ごしください。