JavaScript hook実現

8843 ワード

原型に基づくhook実現:
[bool]hook:params{
    realFunc[String|must]:             ,  unHook;
    hookFunc[Function|must]:   hook  ;
    context[Object|opt]:        ,  hook window      , String.protype.slice,carInstance1
    methodName[String|opt]:              eg:this.Begin = function(){....};
}
[bool]unhook:params{
    realFunc[String|must]:             ,  unHook;
    funcName[String|must]: Hook     
    context[Object|opt]:        ,  hook window      , String.protype.slice,carInstance1
}

<html>
    <head>
        <title>
        title>
        <script type="text/javascript">
        function Hooks(){
        return {
            initEnv:function () {
                Function.prototype.hook = function (realFunc,hookFunc,context,funcName) {
                    var _context = null; //     
                    var _funcName = null; //   

                    _context = context || window;
                    _funcName = funcName || getFuncName(this);
                    _context[realFunc] = this;

                    if(_context[_funcName].prototype && _context[_funcName].prototype.isHooked){
                        console.log("Already has been hooked,unhook first");
                        return false;
                    }
                    function getFuncName (fn) {
                        //      
                        var strFunc = fn.toString();
                        var _regex = /function\s+(\w+)\s*\(/;
                        var patten = strFunc.match(_regex);
                        if (patten) {
                            return patten[1];
                        };
                        return '';
                    }
                    try{
                        eval('_context[_funcName] = function '+_funcName+'(){
'
+ 'var args = Array.prototype.slice.call(arguments,0);
'
+ 'var obj = this;
'
+ 'hookFunc.apply(obj,args)
'
+ 'return _context[realFunc].apply(obj,args);
'
+ '};'); _context[_funcName].prototype.isHooked = true; return true; }catch (e){ console.log("Hook failed,check the params."); return false; } } Function.prototype.unhook = function (realFunc,funcName,context) { var _context = null; var _funcName = null; _context = context || window; _funcName = funcName; if (!_context[_funcName].prototype.isHooked) { console.log("No function is hooked on"); return false; } _context[_funcName] = _context[realFunc]; delete _context[realFunc]; return true; } }, cleanEnv:function () { if(Function.prototype.hasOwnProperty("hook")){ delete Function.prototype.hook; } if(Function.prototype.hasOwnProperty("unhook")){ delete Function.prototype.unhook; } return true; } }; } var hook = Hooks(); hook.initEnv(); // function test(){ alert('test'); } // 。 : // test , ( ), 。 function hookFunc(){ alert('hookFunc'); } // hookFunc test test.hook(test,hookFunc,window,"test"); window.onload = function(){ // hookFunc test , test , hookFunc。 test(); }
script> head> <body> body> html>
中から理解するとJavaScriptは原型に基づいています.