你的位置:首页 > 软件开发 > Java > 理解JavaScript设计模式与开发应用中发布

理解JavaScript设计模式与开发应用中发布

发布时间:2016-04-28 19:00:05
最近拜读了曾探所著的《JavaScript设计模式与开发应用》一书,在读到发布-订阅模式一章时,作者不仅给出了基本模式的通用版本的发布-订阅模式的代码,最后还做出了扩展,给该模式增加了离线空间功能和命名空间功能,以达到先发布再订阅的功能和防止名称冲突的效果。但是令人感到遗憾的是最 ...

理解JavaScript设计模式与开发应用中发布

  最近拜读了曾探所著的《JavaScript设计模式与开发应用》一书,在读到发布-订阅模式一章时,作者不仅给出了基本模式的通用版本的发布-订阅模式的代码,最后还做出了扩展,给该模式增加了离线空间功能和命名空间功能,以达到先发布再订阅的功能和防止名称冲突的效果。但是令人感到遗憾的是最终代码并没有给出足够的注释。这让像我一样的小白就感到非常的困惑,于是我将这份最终代码仔细研究了一下,并给出了自己的一些理解,鉴于能力有限,文中观点可能并不完全正确,望看到的大大们不吝赐教,谢谢!

  下面是添加了个人注释的最终版代码:

 1 <!DOCTYPE html> 2 <html> 3 <head> 4   <title></title> 5   <meta charset = "utf-8" /> 6 </head> 7 <body> 8 <script type="text/javascript"> 9 var Event = (function(){ //定义立即调用的对象 10     var global = this,  11     Event, 12     _default = 'default'; 13     Event = function(){ 14       var _listen,//私有变量 15       _trigger, 16       _remove, 17       _slice = Array.prototype.slice, 18       _shift = Array.prototype.shift, 19       _unshift = Array.prototype.unshift, 20       namespaceCache = {}, 21       _create, 22       find, 23       each = function( ary, fn ){ 24         var ret; 25         for ( var i = 0, l = ary.length; i < l; i++ ){ 26           var n = ary[i]; 27           ret = fn.call( n, i, n); 28           //n(args) 29         } 30         return ret; 31       }; 32       _listen = function( key, fn, cache ){ 33         if ( !cache[ key ] ){ 34           cache[ key ] = []; 35         } 36         cache[key].push( fn ); 37       }; 38       _remove = function( key, cache ,fn){ 39  40         if ( cache[ key ] ){ 41           var fns = cache[key]; 42           if( fn ){ 43             for( var i = fns.length - 1; i >= 0; i-- ){ 44               //原文for( var i = cache[ key ].length; i >= 0; i-- ){ 45               //if( cache[ key ] === fn )我认为不妥。 46               if( fns[i] === fn ){ 47                 fns.splice( i, 1 ); 48               } 49             } 50           }else{ 51             cache[ key ] = []; 52           } 53         } 54       }; 55       _trigger = function(){ 56         var cache = _shift.call(arguments), 57         key = _shift.call(arguments), 58         args = arguments, 59         _self = this, 60         ret, 61         stack = cache[ key ]; 62         if ( !stack || !stack.length ){ 63           return; 64         } 65         return each( stack, function(){ 66           return this.apply( _self, args );//_self = object{} //n(args) 67         }); 68       }; 69       _create = function( namespace ){ 70         var namespace = namespace || _default; 71         var cache = {}, 72         offlineStack = [],  73         // 离线事件 74         ret = { 75           listen: function( key, fn, last ){ 76             _listen( key, fn, cache ); 77             if ( offlineStack === null ){ 78               return; 79             } 80             if ( last === 'last' ){ 81               offlineStack.length && offlineStack.pop()();  82             }else{ 83               each( offlineStack, function(){ 84                 this(); 85               }); 86             } 87             offlineStack = null; 88           }, 89           one: function( key, fn, last ){ 90             _remove( key, cache ); 91             //移除已存在的listen事件 92             this.listen( key, fn ,last ); 93           }, 94           remove: function( key, fn ){ 95             _remove( key, cache ,fn); 96           }, 97           trigger: function(){ 98             var fn, 99             args,100             _self = this;101             _unshift.call( arguments, cache );102             args = arguments;103             fn = function(){104               return _trigger.apply( _self, args );105               //_self的作用是将—trigger方法绑定到ret里面来,从而能使用args106 107             };108             if ( offlineStack ){109               return offlineStack.push( fn );110             }111             return fn();112           }113         };114         return namespace ?115         ( namespaceCache[ namespace ] ? namespaceCache[ namespace ] :116           namespaceCache[ namespace ] = ret )117         : ret;118       };119       return { 120       //所有方法均先创建一个离线空间 调用create方法,并传递空参数, 返回ret = object{};121         create: _create,122         one: function( key,fn, last ){123           var event = this.create( );124           event.one( key,fn,last );125         },126         remove: function( key,fn ){127           var event = this.create( );128           event.remove( key,fn );129         },130         listen: function( key, fn, last ){131           var event = this.create( );132           event.listen( key, fn, last );133         },134         trigger: function(){135           var event = this.create( ); 136           //event = ret ;137           event.trigger.apply( this, arguments ); 138           //将arguments传递给ret.trigger139         }140       };141     }();142     return Event;143   })();144 Event.trigger( 'click', 5 ); 145   // 将其存入offlineStack等待调用146 Event.listen( 'click', function( a ){   147 console.log( a );    148 });149 Event.create( 'namespace1' ).listen( 'click', function( a ){  150  console.log( a ); 151  }); 152  // namespace的作用是,没有时,我们返回简单的ret对象。有时,我们返回namespase下的一个键值为namespase1的对象153 154 Event.create( 'namespace1' ).trigger( 'click', 1 );155  // 将调用namespase1的trigger方法 156 Event.one('click',function(a){157   console.log("this is the one's "+a);158 } ,"last");

 

海外公司注册、海外银行开户、跨境平台代入驻、VAT、EPR等知识和在线办理:https://www.xlkjsw.com

原标题:理解JavaScript设计模式与开发应用中发布

关键词:JavaScript

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。