また JavaScript

  • 投稿日:
  • by
  • カテゴリ:

前の記事 http://archive.guma.jp/2010/02/javascript.html で書いた「それっぽいクラス定義」で、インスタンスを作る関数の戻り値にいわゆるクラスメソッドを突っ込む部分が二段構えになってるのは。

    var that = {};

    var init = function(opts){
        method.prepare(opts);
        return that;
    }
    that.init = init;

ここがどうして var that = { init: function(){ ... } }; となっていないのか。

次の例で見てみるとわかるけど、クラスメソッドから別のクラスメソッドを呼び出すのが安全になるから。

var createRequest = function(method, param){
    var that = {};

    var init = function(opts){
        method.prepare(opts);
        return that;
    }
    that.init = init;

    var send = function(sender){
        sender.send(that);
        return that;
    }
    that.send = send;

    var setParam = function(k, v){
        param[k] = v;
        return that;
    }
    that.setParam = setParam;

    var getparam = function(k){
        return param[k];
    }
    that.getParam = getParam;

    var setHost = function(h){
        return setParam("host", h);
    }
    that.setHost = setHost;

    return that;
}

var request = createRequest("GET", { id: "boeboe" });

ここで setHost() は内部的に setParam() を呼び出してるけど、呼び出してるのは createRequest() 中で定義されてる setParam() と明確に固定されることになる。だから、作ったインスタンスの setParam() を上書きしたとしても、setHost() が呼び出すのは元々の setParam() と保証されるわけで。

var request = createRequest("GET", { id: "boeboe" });
request.setParam = function(o, k, v){
    o[k] = v;
    return;
}

とかできてしまうんだけど、こうしたとしても setHost() は createRequest() 内の setParam() を呼び出すように固定されててここは上書きできないから、後から変更を加えられても確実に動作するわけです。
まぁ request.setHost を上書きされてしまうと意味ないんですが、そのときにちゃんと動作するかどうかは上書きした人の責任になるから気にする必要はないかと。それに request.setHost を上書きしたとしても、別の場所で creareRequest() して得られるインスタンスには全く影響がないわけですし。

さらに、スコープ的には後付けの setParam() から createRequest() の内部が見えなくなっているので、後からいくらメソッドとかを上書きしようと method とか param とかの変数を変更することはできません。
安全ですね。