javascriptでAspect

http://d.hatena.ne.jp/m-hiyama/20050928/1127869442に関してメモ。
単純に関数を乗っ取る場合は下のようにすれば良さそう。

var wrap = function(original,before,after){
  var func = function(){
    before.apply(this,arguments);
    var result = original.apply(this,arguments);
    after.apply(this,arguments);
    return result;
  };
  func.__proto__ = original;//__proto__チェーンを処理
  //func.name = original.name;//nameの書き換えが出来ない!ちょっと不服。
  func.toString = function() {
    return func.__proto__.toString();
  };//AspectのtoStringは全部同じなので隠す。
  return func;
};

var obj = { _x:"X", getX:function(){return this._x;} };
alert(obj.getX());
// 乗っ取りの実行
obj.getX = wrap(obj.getX,
                function(){alert("DO BEFORE");},
                function(){alert("DO AFTER");});
alert(obj.getX());

afterにresultも渡す方が実用的だが、簡単のため省略した。ついでに言えば、beforeとafterを一つのクロージャーで包んでおくと、二つにまたがった変数を扱えて良いかもしれない。