(dev)juginon-blog

勉強したこと、趣味のこと。

【JavaScript】入門編 継承について

インターン始まってjsPrimer.netというネットで見れるJavaScriptの入門書を読んでいる次第であります。わかったつもりになってたけどイマイチよくわかってなかった継承についてまとめたいと思います。

jsPrimerは誰でも閲覧可能です。

jsPrimer.net

継承とは

クラスの機能や構造を引き継いだ新しいクラスを定義すること。

使い方

新しいクラスを宣言するときに extends 親クラス を書くだけ。

  • extends を使って定義した子クラスから親クラスを参照するには super を使う。
  • classは必ず constructor メソッドを持つが、これは継承した子クラスでも同じ。

例:

class Parent {
    constructor(...args) {
        console.log("Parentコンストラクタの処理", ...args);
    }
}
// Parentを継承したChildクラスの定義
class Child extends Parent {
    constructor(...args) {
        // Parentのコンストラクタ処理を呼びだす
        super(...args);
        console.log("Childコンストラクタの処理", ...args);
    }
}
const child = new Child("引数1", "引数2");
// "Parentコンストラクタの処理", "引数1", "引数2"
// "Childコンストラクタの処理", "引数1", "引数2"
  • constructor メソッドで何も処理を行わない場合は constructor は省略可能。 => extends をした時点で、
class Parent {}
class Child extends Parent{
}

と例えば書いたとしたとき、

class Parent {}
class Child extends Parent {
    constructor(...args) {
        super(...args); // 親クラスに引数をそのまま渡す
    }
}

これと同じことを書いていることになる。( ここ自分的に重要 ) もしコンストラクタで何か処理をする場合で、かつ親クラスに引数を渡したい場合は super(...args) と書くということ。

  • class構文では、必ず親クラスのコンストラクタ処理( super() )を先に行い、その次に子クラスのコンストラクタ処理を行う。

理由: super() で親クラスのコンストラクタ処理を呼び出さないと this に触れたとき SyntaxError になるから。

  • そのほかにも super() は子クラスから親クラスのコンストラクタ処理を呼び出すときに使える。
  • super.プロパティ名 で親クラスのプロトタイプメソッドを参照できる。

例:

class Parent {
    method() {
        console.log("Parent#method");
    }
}
class Child extends Parent {
    method() {
        console.log("Child#method");
        // `this.method()`だと自分(`this`)のmethodを呼び出して無限ループする
        // そのため明示的に`super.method()`とParent#methodを呼びだす
        super.method();
    }
}
const child = new Child();
child.method(); 
// コンソールには次のように出力される
// "Child#method"
// "Parent#method"

自分的に覚えておきたい挙動はこんな感じ。最近わかったけど、マジで自分のコードをリーダブルにするのって大変。読みやすいコードを書く練習をしなければいかん、と改めて思いました。