JSフックのメカニズムと実現

6119 ワード

JSフックのメカニズムと実現
[フックとは何か]
WordPressに触れたことのある友人なら誰でも知っているように、WPのプログラムではフックのような関数を実行することができますが、もちろんこのPHPで実現されたフックです.JAVACSCRIPTでも同様の機能が実現できる.
フックは、実行する必要がある関数または他の一連の動作を統合されたエントリに登録し、プログラムはこのフックを呼び出すことで登録された関数を実行します.
[なぜフックを使うのか]
多くの友达はwindowのような関数を書きます.onload、$(document).readyなど、1つのページに類似の関数が1つ以上書かれていますが、これらの実行する必要がある関数を統一的なエントリで実行するにはどうすればいいですか(つまり、ページはwindow.onloadのような関数を1つだけ実行する必要があります).
この場合、HOOKを使用して実装できます(window.onloadを例に挙げると)、ページのロード時に実行する関数をエントリに登録する必要があります.たとえば、次のようにします.
view source
print ? 01. function   func1() 02. { 03. // .... 04. } 05. function   func2() 06. { 07. // .... 08. } 09. hooks.addAction( "loaded" , func1);     // 10. hooks.addAction( "loaded" "func2" );
上にはloadedフックに2つの関数が掛けられていることを示しています.次に、次のようなフックを実行します.
view source
print ? 1. window.onload =  function () 2. { 3. hooks.doAction( "loaded" ); 4. }
これにより、前にどれだけの関数を掛けてもaddAction(「loaded」、function)、hooks.doAction(「loaded」)はここで統一的に実行された.
[JSフックの実装方法]
原理は比較的簡単で、hook配列を定義し、addAction時に関数pushをhook配列に、doAction時にhook配列の関数を逐一呼び出す.
view source
print ? 01. function   hooks() 02. { 03. this .queue =  new   Array(); 04. } 05.
  06. hooks.prototype.addAction =  function (hook, func) 07. { 08. this .queue[hook] =  new   Array(); 09. if ( typeof   func ==  'function' ) { 10. this .queue[hook].push(func); 11. else   if ( typeof   func ==  'string' ) { 12. this .queue[hook].push( this .window[func]); 13. } 14. } 15.
  16. hooks.prototype.doAction =  function (hook) 17. { 18. var   parameters = Array.prototype.slice.call(arguments, 1); 19. var   functions =  this .queue[hook]; 20. for ( var   i=0; i < functions.length; i++) 21. { 22. this .call_user_func_array(functions[i], parameters); 23. } 24. return   true ; 25. } 26.
  27. hooks.prototype.call_user_func_array =  function (cb, parameters) 28. { 29. if   ( typeof   cb ===  'string' ) { 30. func = ( typeof   this [cb] ===  'function' ) ?  this [cb] : func = ( new Function( null 'return '   + cb))(); 31. else   if   (cb  instanceof   Array) { 32. func = (  typeof   cb[0] ==  'string'   ) ? eval(cb[0]+ "['" +cb[1]+ "']" ) : func = cb[0][cb[1]]; 33. else   if   ( typeof   cb ===  'function' ) { 34. func = cb; 35. } 36. if   ( typeof   func !=  'function' ) { 37. throw   new   Error(func +  ' is not a valid function' ); 38. } 39. if ( typeof   parameters ==  'undefined' ) { 40. var   tmp_ary = []; 41. var   parameters = Array.prototype.slice.call(tmp_ary, 1);  42. } 43. return   ( typeof   cb[0] ===  'string' ) ? func.apply(eval(cb[0]), parameters) : 44. typeof   cb[0] !==  'object'   ) ? func.apply( null , parameters) : func.apply(cb[0], parameters); 45. }
上はJSフック関数の定義ですが、不適切な点があれば、ご指摘ください.