js模块和级联

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 }
原文地址:https://www.cnblogs.com/yuyuj/p/4525595.html