6時だョ!!全員集合!!

Rails・JavaScrictを中心にアウトプットします。

2022年1月25日 JavaScript (JS Primer)ビルトインオブジェクトの継承

ビルトインオブジェクトの継承

今回は「ビルトインオブジェクトのコンストラクタも継承出来る」ということについて学んでいきます。

ビルトインオブジェクトにはArray、String、Object、Number、Error、Dateなどのコンストラクタがあります。 class構文ではこれらのビルトインオブジェクトを継承できます。

次のコードでは、ビルトインオブジェクトであるArrayを継承して独自のメソッドを加えたMyArrayクラスを定義しています。 継承したMyArrayはArrayの性質であるメソッドや状態管理についての仕組みを継承しています。 継承した性質に加えて、MyArray#firstやMyArray#lastといったアクセッサプロパティを追加しています。

class MyArray extends Array {
    get first() {
        if (this.length === 0) {
            return undefined;
        } else {
            return this[0];
        }
    }

    get last() {
        if (this.length === 0) {
            return undefined;
        } else {
            return this[this.length - 1];
        }
    }
}

// Arrayを継承しているのでArray.fromも継承している
// Array.fromはIterableなオブジェクトから配列インスタンスを作成する
const array = MyArray.from([1, 2, 3, 4, 5]);
console.log(array.length); // => 5
console.log(array.first); // => 1
console.log(array.last); // => 5

firstとlastはRubyでは配列の先頭と最後の値を取得できるインスタンスメソッドとしてArrayに定義されていますが、JavaScriptでは定義されていないので、ここではアクセッサプロパティから呼び出しています。

Arrayを継承したMyArrayは、Arrayが元々持つlengthプロパティやArray.fromメソッドなどを継承しているので利用できます。

Array.from()メソッド

上記のコードはArray.from()を使用していましたが以下のように記述した場合と同じ結果になります。

const array = new MyArray(1, 2, 3, 4, 5);

今回のコードではインスタンス化にnew演算子を使用していないため、それについても調べてみたところ、 MDNには以下のように書いてありました。

Array.from のような静的メソッドは Array のサブクラスに「継承」され、Array ではなくサブクラスのインスタンスを生成します。

Array.fromはArrayクラスの静的メソッドです。(インスタンス化せずにメソッドを使えている=静的メソッド)

このため、Arrayクラスを継承したMyArrayは親クラスの静的メソッドであるfromメソッドをインスタンス化せずに使用することが出来る事を示すためにArray.fromを使用しています。

復習

反復可能な(iterables) オブジェクト

アクセッサプロパティ

クラスに対してメソッドを定義できますが、メソッドはメソッド名()のように呼び出す必要があります。 クラスでは、プロパティの参照(getter)、プロパティへの代入(setter)時に呼び出される特殊なメソッドを定義できます。 このメソッドはプロパティのように振る舞うためアクセッサプロパティと呼ばれます。

次のコードでは、プロパティの参照(getter)、プロパティへの代入(setter)に対するアクセッサプロパティを定義しています。 アクセッサプロパティはメソッド名(プロパティ名)の前にgetまたはsetをつけるだけです。 getter(get)には仮引数はありませんが、必ず値を返す必要があります。 setter(set)の仮引数にはプロパティへ代入する値が入りますが、値を返す必要はありません。

まとめ

この章ではクラスについて学びました。

  • JavaScriptのクラスはプロトタイプベース
  • クラスはclass構文で定義できる
  • クラスで定義したメソッドはプロトタイプオブジェクトとプロトタイプチェーンの仕組みで呼び出せる
  • アクセッサプロパティはgetterとsetterのメソッドを定義することでプロパティのように振る舞う
  • クラスはextendsで継承できる
  • クラスのプロトタイプメソッドと静的メソッドはどちらも継承される
  • class構文でしか実現できない機能はなく、読みやすさやわかりやさのために導入された構文という側面もあります。そのため、JavaScriptのclass構文は糖衣構文(シンタックスシュガー)と呼ばれることがあります。

シンタックスシュガーがわからない方

参考

JS primer ビルトインオブジェクトの継承

Array.from()メソッド

シンタックスシュガー