JavaScriptでのクラス定義

  • 68
    いいね
  • 2
    コメント
この記事は最終更新日から1年以上が経過しています。

よく使うパターン

あんまり意味のないHelloクラスを定義してみる

var Hello = (function(){
    // constructor
    function Hello(name){
        this._name = name;
    }

    // private method
    function say(message){
        console.log(message + ', ' + this._name);
    }

    // public method
    function hello(){
        say.call(this, 'Hello');
    }

    Hello.prototype = {
        // constructor 修正
        constructor: Hello,
        // 以下 public メソッド
        hello: hello
    };
    return Hello;
}());

このパターンのポイントは、即時関数内にクラスに関係あるメソッドや変数をまとめるところ。
クラスの定義以外は、即時関数の外を汚さない。
また、公開したいインターフェースは最後のprototypeに列挙するだけでいいのもポイント高い。

継承

このパターンで継承する場合ちょっとややこしくなる。
というかJSで継承しようとするとややこしくなる。

var Animal = (function(){
    function Animal(name){
        this._name = name;
    }
    function say(){
        throw new Error('not implemented');
    }
    Animal.prototype = {
        constructor: Animal,
        say: say
    };
    return Animal;
}());

var Dog = (function(){
    function Dog(name){
        // super call
        Animal.call(this, name);
    }
    function say(){
        console.log('bowwow');
    }
    // Animal.prototype をプロトタイプチェーンに追加したいが、コンストラクタが邪魔なのでちょっと細工する
    Dog.prototype = (function(){
        function F(){}
        F.prototype = Animal.prototype;
        return new F();
    }());

    // 複数メソッドを定義する場合、並べて書かないとダメなのであまりイケてない
    Dog.prototype.constructor = Dog;
    Dog.prototype.say = say;
    return Dog;
}());

Object.create が使えるなら

ちょっとスマートに書ける

var Animal = (function(){
    function Animal(name){
        this._name = name;
    }
    function say(){
        throw new Error('not implemented');
    }
    Animal.prototype = {
        constructor: Animal,
        say: say
    };
    return Animal;
}());

var Dog = (function(){
    function Dog(name){
        // super call
        Animal.call(this, name);
    }
    function say(){
        console.log('bowwow');
    }
    // すっきり!
    Dog.prototype = Object.create(Array.prototype);

    // でもここはやっぱりイケてない
    Dog.prototype.constructor = Dog;
    Dog.prototype.say = say;
    return Dog;
}());