[javascript] jQueryみたいにオブジェクトを扱えるような方法を考えてみた。

prototype.jsからjQueryに切り替えてjQueryが良く出来ていることにビックリしまくり。名前空間は汚さないし直感的に出来てとても便利!

っで、インスパイア(一度言ってみたかった)されてにた感じのライブラリ実装方法を考えてみた。

  • 7/5 バグってたので修正。

コード

Firefox + Firebugを使ってる場合は、consoleにコード丸ごと貼付けて実行してみてください。

// ---------------------------
// core
var jMill=function( arg ){
  var retval = {
    val: arg, value: arg,
    toString:function(){ return arg.toString(); }
    };
  if(typeof arg == 'undefined' || arg == null) return retval;

  var funcs = jMill._methodRules;
  for(var prop in funcs){
    var p = (funcs[prop])( arg );
    if(typeof p == 'function'){
      retval[prop]=(function(p){
        return function(){return jMill(p.apply(this,arguments));};
      })(p);
    }
  }
  return retval;
};
jMill._methodRules = {}; // method rules
jMill.fn  = {}; // public function
jMill.noConflict = function(){ return jMill; };
jMill.setMethodRule = function(name, func){
  if(name == 'val' || name == 'value') throw 'method name duplicate error.';
  jMill._methodRules[name]=func;
};

// ---------------------------
// functions

jMill.setMethodRule('toCurrency', function( val ){
  var t=typeof val;
  if( !( t == 'string' || t == 'number' ) ) return;
  return function(){ return jMill.fn.toCurrency(val); };
});

jMill.fn.toCurrency=function(num){
  return (num+'').replace(/([0-9])(?=([0-9]{3})+$)/g,'$1,');
};


// sample
var ret = jMill(19800);
for(var i in ret) console.log( 'prop',i );
console.log( 'jMill(19800).toCurrency()=', jMill(19800).toCurrency().val);

結果は次のようになります。

prop val
prop value
prop toString
prop toCurrency
jMill(19800).toCurrency()= 19,800

説明

  • jMill.fn.${関数名}で関数の定義
  • jMill.setMethodRule(${メソッド名}, ${関数})でjMill(${評価値})で指定できるメソッドを定義
    • ${関数}は評価時に実行される。
      • 評価値が引数で渡される。
      • 戻り値がfunctionの場合、jMill(評価値)のメソッドとして定義される。
  • jMill(評価値)の戻り値は常にオブジェクト
    • 戻り値には必ずvalue、valとtoString()がある
    • value、valで評価値が取得できる。
    • toString()でStringオブジェクトが受け取れる。(nullとかの場合エラる)
  • jQueryっぽくjMill.noConflict()を作ってみた。
  • メリットとか
    • jMill.fn.*を別ファイルにしておけば要所要所で切り替えられる
    • jMill(${評価値})を使うよりjMill.fn.*を使った方がコストがかからないので速度優先のときはコッチを使う
    • jMill(${評価値})が必ずオブジェクトだから、使えるメソッド一覧が取得できる。

懸念

  • テスト不足と実際に使ってないのでイタいバグがあるかもしれない。(あったから直したまだあるかも)

参考