Enchanced Method Hooking

http://youngman.kr/?p=1540

by Ukjin Yang

HTML

<button id='test'></button>

JavaScript

function hook(uiObj, op) {
    op = op || {};
  for(var key in uiObj) {
    var func = uiObj[key];
    
    if(typeof(func) == "function") {
      (function(funcName, funcObj) {
        uiObj[funcName] = function() {
            
            if(typeof(op.before)==='function'){
                op.before.apply(this,[funcName,funcObj].concat(arguments));
            }
            
            var resultObj = funcObj.apply(this, arguments);
            var nEnd = Date.now(); 
            
            if(typeof(op.after)==='function'){
                resultObj = op.after.apply(this,[funcName,resultObj].concat(arguments)) || resultObj;
            }
            
            return resultObj;
        };
      })(key, func);
    }
  }
  
  if(uiObj.__proto__ != null) hook(uiObj.__proto__);
    return uiObj;
}

var Test = function(){
    hook(this, {
        before: function(name,body){
            for(var i=0;i<1e8;i++){}
            console.log('Before func: '+name);
        },after: function(name,result){
            for(var i=0;i<1e8;i++){}
            console.log('After func: '+name);
        }
    });
};
Test.prototype = {
    a: function(){console.log('a');},
    b: function(){console.log('b');},
    c: function(){console.log('c');},
    d: function(){console.log('d');},
    e: function(){console.log('e');}
};

var test = new Test();
test.a();
test.e();
test.d();
test.c();
test.b();

test = hook(document.getElementById('test'),{
        before: function(name,body){
            for(var i=0;i<1e8;i++){}
            console.log('Before func: '+name);
        },after: function(name,result){
            for(var i=0;i<1e8;i++){}
            console.log('After func: '+name);
        }
});
test.onclick=function(){
    console.log('clicked at '+new Date().toLocaleString());
};
test.appendChild(document.createTextNode('test now!'));