最近拜读了曾探所著的《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
(#换成@)。