[什麼是鉤子]javascript
接觸過WordPress的朋友都知道,WP的程序中能夠執行相似鉤子的函數,固然是這PHP實現的鉤子。在JavaScript中同樣能夠實現相似的功能。php
用一句話來形容一下:鉤子是將須要執行的函數或者其餘一系列動做註冊到一個統一的入口,程序經過調用這個鉤子來執行這些已經註冊的函數。java
[爲何要用鉤子]數組
不少朋友都會寫一些函數,相似window.onload、$(document).ready等,並且一個頁面不止一處寫到相似的函數,如何讓這些須要執行的函數在一個統一的入口執行(即頁面只須要執行一個相似window.onload的函數)?app
這時咱們能夠藉助HOOK來實現,(以window.onload爲例)將因此須要在頁面加載的時候執行函數都註冊到一個入口,如:函數
function func1() {// .... }function func2() {// .... } hooks.addAction("loaded", func1); // 添加函數 hooks.addAction("loaded", "func2");
上面表示在loaded鉤子上掛了兩個函數。而後執行這個鉤子,如:this
window.onload = function() { hooks.doAction("loaded"); }
這樣不管在以前掛多少函數hooks.addAction("loaded", function),在hooks.doAction("loaded")這裏都被統一執行了。spa
[JS鉤子如何實現].net
原理比較簡單,定義一個hook數組,addAction時將函數push到hook數組,doAction時將hook數組裏的函數逐一調用。prototype
function hooks() {this.queue = new Array(); } hooks.prototype.addAction = function(hook, func) {this.queue[hook] = new Array();if(typeof func == 'function') {this.queue[hook].push(func); } else if(typeof func == 'string') {this.queue[hook].push(this.window[func]); } } hooks.prototype.doAction = function(hook) {var parameters = Array.prototype.slice.call(arguments, 1);var functions = this.queue[hook];for(var i=0; i < functions.length; i++) {this.call_user_func_array(functions[i], parameters); }return true; } hooks.prototype.call_user_func_array = function(cb, parameters) {if (typeof cb === 'string') { func = (typeof this[cb] === 'function') ? this[cb] : func = (newFunction(null, 'return ' + cb))(); } else if (cb instanceof Array) { func = ( typeof cb[0] == 'string' ) ? eval(cb[0]+"['"+cb[1]+"']") : func = cb[0][cb[1]]; } else if (typeof cb === 'function') { func = cb; }if (typeof func != 'function') {throw new Error(func + ' is not a valid function'); }if(typeof parameters == 'undefined') {var tmp_ary = [];var parameters = Array.prototype.slice.call(tmp_ary, 1); }return (typeof cb[0] === 'string') ? func.apply(eval(cb[0]), parameters) :. ( typeof cb[0] !== 'object' ) ? func.apply(null, parameters) : func.apply(cb[0], parameters); }