Mach3.laBlog

細かすぎて伝わらないjQuery拡張 (3) “$.classify” – Advent Calendar 2016

この記事は賞味期限切れです。(更新から1年が経過しています)

$.classify() はクラスライクなオブジェクトを作成するための関数です。

ちゃんとしたクラスは新しいバージョンのEcmaScriptで利用することができますが、 環境を選んだり Babel してあげないといけなかったりするので、 レガシーな仕組みを利用する場面はまだまだあるのではないでしょうか。

$.classify(props)

使い方

プロパティのオブジェクトを渡して初期化します。 返ってきた関数オブジェクトは new してインスタンスを作ります。 命名等はES6~のクラス構文に少し寄せた形にしています。

var Person = $.classify({

    name: null,
    age: null,

    _constructor: function(name, age){
        this.name = name;
        this.age = age;
    },

    hello: function(){
        return "こんにちは!わたしは" + this.name + "、" + this.age + "歳さ!";
    }

});

var john = new Person("ジョン", 23);
john.hello(); // <= "こんにちは!わたしはジョン、23歳さ!"

継承はクラスオブジェクトのメソッドでおこなえます。

var Engineer = $.classify({

    _constructor: function(name, age){
        this._super(name, age);
    },

    work: function(){
        return "カタカタカタカタ…ターーーンッ!!";
    }

});

// .extend() で継承
Engineer.extend(Person);

var bob = new Engineer("ボブ", 28);
bob.hello(); // => "こんにちは!わたしはボブ、28歳さ!";
bob.work(); // => "カタカタカタカタ…ターーーンッ!!";

親クラスのコンストラクタは _super で呼び出せます。

コード

$.classify = function(props){
    var ClassObject = function(){
        if($.isFunction(this._constructor)){
            this._constructor.apply(this, arguments);
        }
    };
    $.extend(true, ClassObject.prototype, props);
    ClassObject.extend = function(sup){
        var key;
        sup = $.isFunction(sup) ? sup.prototype : sup;
        for(key in sup){
            if(sup.hasOwnProperty(key) && key !== "_constructor"){
                this.prototype[key] = sup[key];
            }
        }
        this.prototype._super = function(){
            sup._constructor.apply(this, arguments);
        };
        return this;
    };
    return ClassObject;
};

シンプルな方が使いやすい

クラスを作る関数やライブラリは長いこと色々書いてみました。 中には色々な便利機能がついてるもの(初期化時に色々やってくれたり)や、 コアクラス的なものを揃えてみたりもしたのですが、 結局のところシンプルイズベストだという所に今は落ち着いています。

「あるとイイかな」と思って色々細かい機能をつけたところでそれらを利用する場面はごくごく限られていて(下手すると一度も使われない)、 何より重要なのは、使う自分自身がそんな細かい機能達をおぼえていられないという事です。

コメント

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*