見出し画像

【JavaScript】JSでもクラスを使ってみる

jsで複雑なもの作るのあんまり好きじゃないんですが、にっちもさっちも行かない案件が出てきたので、jsでもクラスを使ってうごうごしていきたいと思います。ざーっくりとだけど、継承まで一気にいくぜ。

先に、後で見返すとき用の書式まとめ。

class Elements{
    constructor(hoge){
        this.hoge = hoge;
    }
    getElements(id_preffix){
        // 処理
    }
}

class ChildElements extends Elements{
    constructor(hoge,fuga){
        super(hoge)  // スーパークラスのコンストラクタを呼ぶ
        let nya = super.getElements(fuga)  // スーパークラスのメソッドを使う
        let wan = this.process(nya)  // 子クラスのメソッドを使う
    }
    
    process(nya){
        let foo = nanika_no_syori(super.hoge)  // スーパークラスのプロパティを使う
        let bar = nanika_no_syori(this.nya)  // 自クラスのプロパティを使う
        // 処理
    }
}

詳細はこちらで。

また、「クラスの継承」についての考え方そのものは他の言語でやるときと同じなので

この辺とか

この辺とかでまとめています。

本題

今回は、「HTMLの中にある、ABCの3つの部屋の、定員と、利用中人数と、利用料金の一覧を表示する表」から、「人数に関わるセルのリスト」と、「料金に関わるセルのリスト」というオブジェクトの2種類を作りたいものとします。

HTMLはこんな感じだとします

<html>
<head>(略)</head>
<body>
    <div id="main_table">
        <div id="max"> <!-- 定員 -->
            <div id="max_a">10</div>
            <div id="max_b">5</div>
            <div id="max_c">3</div>
        </div>
        <div class="now"> <!-- 利用中の人数 -->
            <div id="now_a">7</div>
            <div id="now_b">5</div>
            <div id="now_c">0</div>
        </div>
        <div class="charge"> <!-- 料金 -->
            <div id="charge_a">7</div>
            <div id="charge_b">5</div>
            <div id="charge_c">0</div>
        </div>
    </div>
</body>
</html>

それぞれセルに当たる部分のdivに、idとして共通の接頭辞+部屋名が入っています。これで各セルを特定出来るようになっています。

親クラスを作る

「人数関連」のクラスと「料金関連」のクラスで共通で使う処理を抜き出して親クラスを作ります。

class Elements{
    constructor(room_list){
        this.room_list = room_list;
    }
    
getElements(id_preffix){
    let elements = new Map();
    for(let index in this.room_list){
        let room = this.room_list[index];
        let id = id_preffix + room;
        let element = document.getElementById(id);
        elements.set(room, element);
    }
}

let ROOMS = ["a", "b", "c"]


コンストラクタは「constructor()」で宣言する。
インスタンスメソッドにはfunctionとかmethodとか付けないでいきなりメソッド名書き始めてOK。

今回は、部屋名のリストを受け取るコンストラクタと、idの接頭辞を受け取って、「その接頭辞を持ち、部屋名のリストと合致するid」が付与された要素を全て取得する、getElementsメソッドを用意します。

getElementsメソッド内ではMapを使って、ちゃんとした連想配列を用意してあげました。Mapオブジェクトの使い方はこちらで。Mapにしておけばforの処理とかが楽ですが対応ブラウザにはお気をつけて。

子クラスを作る

「人数関連」クラスと「料金関連」クラスを作ります。実際に使うのはこっち。

class PeopleElements extends Elements{
    constructor(room_list){
        super(room_list);
        this.capacity = super.getElements("max_");
        this.now = super.getElements("now_");
    }
}
class PriceElements extends Elements{
    constructor(room_list){
        super(room_list);
        this.price = super.getElements("price_");
    }
}

クラスを宣言した後に「extends 親クラス名」で親クラスを継承出来ます。

コンストラクタの一番最初に、「super()」を呼んで親クラス(スーパークラス)のコンストラクタを呼び出すことで、親クラスのプロパティやメソッドが実体化します。

javaやpythonの継承と違って、継承したメソッドやクラスはthisじゃなくて明示的にsuperって指定してあげないと使えないっぽい。なので、親クラスで作ったgetElementsメソッドを使う時は「super.getElements」で呼ぶ。

インスタンスを作る

let rooms = ["a", "b", "c"]
let people_elements = new PeopleElements(rooms);
let price_elements = new PriceElements(rooms);

newを使ってコンストラクタを呼んで、インスタンスを作ればOK。

ひとまず親クラスと子クラス作って、インスタンスが作れるところまで。

この記事が気に入ったらサポートをしてみませんか?