标签:
1、模块
模块模式的一般形式是:一个定义了私有变量和函数的函数,利用闭包创建可以访问私有变量和函数的特权函数,最后返回这个特权函数,或者把它们保存到一个可访问的地方。使用模块模式就可以摒弃全局变量的使用,它促进了信息隐藏和其他优秀的设计实践。对于应用程序的封装,或构造其他单例对象,模块模式非常有效。模块模式也可以用来产生安全的对象,如下例中我们想要构造一个用来产生序列号的函数:
1 var serial_maker = function(){ 2 var prefix = ""; 3 var seq = 0; 4 return { 5 set_prefix : function(pre){ 6 prefix = new String(pre); 7 }, 8 set_seq : function(s){ 9 if(typeof s === "number"){ 10 seq = s; 11 }else{ 12 throw { 13 name : "ErrorType", 14 message: "seq must be number" 15 }; 16 } 17 }, 18 gensym : function(){ 19 //序列号为前缀加序号 20 var result = prefix + seq; 21 seq += 1; 22 return result; 23 } 24 }; 25 }; 26 var seqer = serial_maker(); 27 seqer.set_prefix("Q"); 28 try{ 29 seqer.set_seq(1000); 30 document.writeln(seqer.gensym());//Q1000 31 document.writeln(seqer.gensym());//Q1001 32 document.writeln(seqer.seq());//undefined 33 var seqer_2 = serial_maker(); 34 document.writeln(seqer.gensym());//0 35 }catch(e){ 36 document.write(e.name + ":" + e.message); 37 }
seqer包含的方法都没有用到this或that。因此没有办法损害seqer。除非调用对应的方法,否则没法改变prefix或seq的值。seqer对象时可变的,所以它的方法可能会替换掉,但替换后的方法依然不能访问私有成员。seqer就是一组函数的集合,而且那些函数被授予特权,拥有使用或修改私有状态的能力。上例可以采用构造函数的方式实现:
1 var Serial_maker = function(){ 2 var prefix = ""; 3 var seq = 0; 4 this.set_prefix = function(pre){ 5 prefix = new String(pre); 6 }; 7 this.set_seq = function(s){ 8 if(typeof s === "number"){ 9 seq = s; 10 }else{ 11 throw { 12 name : "ErrorType", 13 message: "seq must be number" 14 }; 15 } 16 }; 17 this.gensym = function(){ 18 var result = prefix + seq; 19 seq += 1; 20 return result; 21 }; 22 }; 23 var seqer = new Serial_maker(); 24 seqer.set_prefix("Q"); 25 try{ 26 seqer.set_seq(1000); 27 document.writeln(seqer.gensym());//Q1000 28 document.writeln(seqer.gensym());//Q1001 29 document.writeln(seqer.seq());//undefined 30 }catch(e){ 31 document.write(e.name + ":" + e.message); 32 }
2、级联
有一些方法没有返回值,如果我们让这些返回this而不是undefined,就可以启用级联,如下例:
1 var serial_maker = function(){ 2 var prefix = ""; 3 var seq = 0; 4 return { 5 set_prefix : function(pre){ 6 prefix = new String(pre); 7 return this; 8 }, 9 set_seq : function(s){ 10 if(typeof s === "number"){ 11 seq = s; 12 }else{ 13 throw { 14 name : "ErrorType", 15 message: "seq must be number" 16 }; 17 } 18 return this; 19 }, 20 gensym : function(){ 21 //序列号为前缀加序号 22 var result = prefix + seq; 23 seq += 1; 24 return result; 25 } 26 }; 27 }; 28 var seqer = serial_maker(); 29 seqer.set_prefix("Q"); 30 try{ 31 seqer.set_seq(1000); 32 document.writeln(seqer.set_prefix("Q").set_seq(1000).gensym());//Q1000,采用级联 33 document.writeln(seqer.gensym());//Q1001 34 }catch(e){ 35 document.write(e.name + ":" + e.message); 36 }
标签:
原文地址:http://www.cnblogs.com/yuyuj/p/4525595.html