钩子函数是Windows消息处理机制的一部分,经过设置“钩子”,应用程序能够在系统级对全部消息、事件进行过滤,访问在正常状况下没法访问的消息。钩子的本质是一段用以处理系统消息的程序,经过系统调用,把它挂入系统 --- 百度百科的定义html
个人理解是:钩子函数能够 钩住 我喜欢的东西(在window中就是我喜欢的消息),这应该就是钩子函数叫钩子函数的缘由吧。。?前端
钩子函数的意义(用处)在于:我写了一个window程序,在程序中我写了一段代码(调用window的api来实现钩子),这段代码被系统经过系统调用,把其挂入系统中,而后我就能够对我感兴趣的消息进行处理,编程
我写的这段代码包含有一个回调函数,当有我喜欢的消息发出时,这个回调函数就会执行,因此说,钩子就是指的回调函数api
下面是一个程序挂载全局钩子从而被360拦截的例子(其实360也有钩子,否则怎么知作别人要挂载钩子呢?即360能够拦截“挂载钩子”的消息。这个弹窗就是在360的钩子函数中建立的)app
对于前端来讲,钩子函数就是指再全部函数执行前,我先执行了的函数,即 钩住 我感兴趣的函数,只要它执行,我就先执行。此概念(或者说现象)跟AOP(面向切面编程)很像ide
一个钩子函数的例子函数
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 }