什麼是鉤子函數?

鉤子(HOOK)函數

什麼是鉤子函數?

鉤子函數是Windows消息處理機制的一部分,通過設置“鉤子”,應用程序可以在系統級對所有消息、事件進行過濾,訪問在正常情況下無法訪問的消息。鉤子的本質是一段用以處理系統消息的程序,通過系統調用,把它掛入系統 --- 百度百科的定義

我的理解是:鉤子函數可以 鉤住 我喜歡的東西(在window中就是我喜歡的消息),這應該就是鉤子函數叫鉤子函數的原因吧。。?

鉤子函數的意義(用處)在於:我寫了一個window程序,在程序中我寫了一段代碼(調用window的api來實現鉤子),這段代碼被系統通過系統調用,把其掛入系統中,然後我就可以對我感興趣的消息進行處理,

我寫的這段代碼包含有一個回調函數,當有我喜歡的消息發出時,這個回調函數就會執行,所以說,鉤子就是指的回調函數

下面是一個程序掛載全局鉤子從而被360攔截的例子(其實360也有鉤子,不然怎麼知道別人要掛載鉤子呢?即360可以攔截“掛載鉤子”的消息。這個彈窗就是在360的鉤子函數中創建的)

那麼對於前端,什麼是鉤子函數呢?

對於前端來說,鉤子函數就是指再所有函數執行前,我先執行了的函數,即 鉤住 我感興趣的函數,只要它執行,我就先執行。此概念(或者說現象)跟AOP(面向切面編程)很像

一個鉤子函數的例子

複製代碼

 1 function Hooks(){ 2     return { 3         initEnv:function () { 4             Function.prototype.hook = function (realFunc,hookFunc,context,funcName) { 5                 var _context = null; //函數上下文 6                 var _funcName = null; //函數名 7  8                 _context = context || window; 9                 _funcName = funcName || getFuncName(this);10                 _context[realFunc] = this;11 12                 if(_context[_funcName].prototype && _context[_funcName].prototype.isHooked){13                     console.log("Already has been hooked,unhook first");14                     return false;15                 }16                 function getFuncName (fn) {17                     // 獲取函數名18                     var strFunc = fn.toString();19                     var _regex = /function\s+(\w+)\s*\(/;20                     var patten = strFunc.match(_regex);21                     if (patten) {22                         return patten[1];23                     };24                     return '';25                 }26                 try{27                     eval('_context[_funcName] = function '+_funcName+'(){\n'+28                         'var args = Array.prototype.slice.call(arguments,0);\n'+29                         'var obj = this;\n'+30                         'hookFunc.apply(obj,args)\n'+31                         'return _context[realFunc].apply(obj,args);\n'+32                         '};');33                     _context[_funcName].prototype.isHooked = true;34                     return true;35                 }catch (e){36                     console.log("Hook failed,check the params.");37                     return false;38                 }39             }40             Function.prototype.unhook = function (realFunc,funcName,context) {41                 var _context = null;42                 var _funcName = null;43                 _context = context || window;44                 _funcName = funcName;45                 if (!_context[_funcName].prototype.isHooked)46                 {47                     console.log("No function is hooked on");48                     return false;49                 }50                 _context[_funcName] = _context[realFunc];51                 delete _context[realFunc];52                 return true;53             }54         },55         cleanEnv:function () {56             if(Function.prototype.hasOwnProperty("hook")){57                 delete Function.prototype.hook;58             }59             if(Function.prototype.hasOwnProperty("unhook")){60                 delete Function.prototype.unhook;61             }62             return true;63         }64     };65 }66 67 var hook = Hooks();68 hook.initEnv();69 70 // 這個是要執行的正常的函數71 function test(){72     alert('test');73 }74 75 // 這個是鉤子函數。此鉤子函數內心戲:76 // 我只喜歡test函數,所以我必須出現在她前面(在她前面執行),這樣她才能看到我。77 function hookFunc(){78     alert('hookFunc');79 }80 81 // hookFunc鉤住test82 test.hook(test,hookFunc,window,"test");83 84 window.onload = function(){85   // 由於鉤子函數hookFunc鉤住了test函數,所以test執行時,會先執行hookFunc。86   test();87 }

複製代碼


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章