[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(評価値)の戻り値は常にオブジェクト
- jQueryっぽくjMill.noConflict()を作ってみた。
- メリットとか
- jMill.fn.*を別ファイルにしておけば要所要所で切り替えられる
- jMill(${評価値})を使うよりjMill.fn.*を使った方がコストがかからないので速度優先のときはコッチを使う
- jMill(${評価値})が必ずオブジェクトだから、使えるメソッド一覧が取得できる。
懸念
- テスト不足と実際に使ってないのでイタいバグがあるかもしれない。(あったから直したまだあるかも)
参考
- http://nanto.asablo.jp/blog/2006/10/18/566348
- プリミティブを継承できないものかと調べたけど簡潔にならないのでこの方法はあきらめました。