Module Pattern是JavaScript里面最常见的编码模式。
匿名闭包是这个模式可以实现的前提,例如下面的代码:
1 (function() 2 { 3 function dosomething() 4 { 5 console.log("dosomething"); 6 } 7 })()
上面的(function(){})返回的是一个函数引用,在后面再加()变成这样:(function(){})()表示执行这个函数,所以这样写是可以的,我还以为我以前出错了呢。这是因为我发现这样写也行:
(function () { function dosomething() { console.log("dosomething"); } }());
用括号把这个匿名函数表达式括起来,如果不括起来,会认为这是一个函数定义,所以提示没有函数名出错。
下面我来进入正题:
1,全局导入。通过传入参数,可以避免一些难以管理的代码问题:传入window输出window的高。
1 (function(w) 2 { 3 function dosomething() 4 { 5 console.log(w.screen.height); 6 } 7 dosomething(); 8 })(window);
2,模块的导出。可以让我们在匿名函数里面定义的方法可以给外面的空间使用:
1 var moduleA = (function(w) 2 { 3 var _name = "Hello world"; 4 function getName() 5 { 6 console.log("you can do something before get name"); 7 return _name; 8 } 9 function setName(name) 10 { 11 console.log("you can do something before set name"); 12 _name = name; 13 } 14 function privateDosomething() 15 { 16 console.log(getName() + " " + w.screen.height); 17 } 18 return { 19 publicDosomething:privateDosomething, 20 setName:setName, 21 getName:getName 22 } 23 })(window); 24 moduleA.publicDosomething(); 25 moduleA.setName("Jobs"); 26 console.log(moduleA.getName()); 27 // you can do something before get name
28 // Hello world 1080
29 // you can do something before set name
30 // you can do something before get name
31 // Jobs
3,这样还不够,这样一个module只可以在一个js文件中,要想能够在不同的module里面使用,需要首先使用导入module,然后为module添加属性,然后把module导出:
现在一个module.js的文件里面写下面的代码(假设这是CoderA写的代码):
var moduleA = (function (m) { m.dosomething2= function() { console.log("Hey , this is dosomething2!"); } return m; })(moduleA||{}); //<script src="Module.js"></script> 记得include进主文件
CoderB想用到CoderA写的Module,但是他也想自己加一些属性进去,首先他需要include CoderA的module.js :<script src="Module.js"></script>. 然后他开始敲自己的代码:
1 var moduleA = (function(module,w) 2 { 3 var _name = "Hello world"; 4 function getName() 5 { 6 console.log("you can do something before get name"); 7 return _name; 8 } 9 function setName(name) 10 { 11 console.log("you can do something before set name"); 12 _name = name; 13 } 14 function privateDosomething() 15 { 16 console.log(getName() + " " + w.screen.height); 17 } 18 19 module.setName = setName; 20 module.getName = getName; 21 module.publicDosomething = privateDosomething; 22 23 return module; 24 })(moduleA||{},window); 25 moduleA.publicDosomething(); 26 moduleA.setName("Jobs"); 27 console.log(moduleA.getName()); 28 moduleA.dosomething2(); //这个是CoderA写的代码 29 // you can do something before get name 30 // Hello world 1080 31 // you can do something before set name 32 // you can do something before get name 33 // Jobs 34 // Hey , this is dosomething2!
我们看到, 如果这里,CoderB也写了一个dosomething2属性,这样会覆盖掉A的,我还没想到有什么好的方法。或许可以用一个oldMethiod的变量存起来。