Javascript模块化编程初探

  现如今,web项目越做越大,前端的各种文件也愈发膨胀,随便一个js文件都可能写到1000多行,其中的方法数十个,变量甚至几十个,由于javascript中没有java、c中的块级作用域的概念,如果没有合理的方式编写,都将其写成全局变量,万一一个页面要是引用了多个js文件,而且不是一个人写的,那乐子可大了去了,变量名重复是必不可少的,经常导致一些莫名的bug出现。而且后期的维护也是要人老命的,如果你需要修改或者添加一些变量或者方法,你得十分小心。

针对上面的困境,我们希望能有有一种方式可以结构化管理所有变量和方法,同时轻松实现代码扩展与维护, 蓦然发现合理的编写js代码是多么的重要。

解决思路

一、原来的方式

 1 var count = 25;
 2 var price = 3.4;
 3 var hasMoney = 100;
 4 function cost(count, price){
 5     return count*price;
 6 };
 7 
 8 function giveChange(){
 9         return hasMoney-cost(count, price);
10 }

上面的方式是最直观最便捷的写法,但是这种写法的代价上面说了,是我们所不愿承受的。我们希望所有变量都能有个统一的管理者,这时候“命名空间”就闪亮登场了。

二、对象写法

var calculateMoney = {
    count  : 25,
    prices : 3.4,
    hasMoney : 100,
    cost : function(count, price){
          return count*price;
     },
     giveChange : function(){
           return this.hasMoney-this.cost(this.count, this.prices)  
     }    
}    

  看到这,是不是有些小激动,写法方式很简单,就可以大大的避免了变量的全局污染。不过这种方式还是有些缺陷:暴露了对象中所有的变量和方法。我们更希望只有我们愿意给别人看到的那部分,别人才能看得到。这个要实现也很简单,请看接着看。

三、立即执行函数写法

 1 var calculateMoney = (function(){
 2     var _count = 25;
 3     var _prices = 3.4;
 4     var _hasMoney= 100;
 5 
 6     function _cost(_count , _prices ){
 7          return _count*_prices;   
 8     }
 9     
10      function _giveChange(){
11           return this.hasMoney-_cost(_count, _prices);
12     }        
13     return {
14         hasMoney: _hasMoney,
15        giveChange : _giveChange
16     }    
17 })();

  上面的写法就很完美的解决了隐藏不想给别看的变量和方法,看上去,我们的工作已经很完美的,只是向外提供了hasMoney变量和giveChange方法,而_cost方法是外界所无法接触到的。但是,如果是一个很大的模块,我们要分成很多个小的模块编写,这些模块又该如何做到继承和扩展呢?如果模块这些模块的加载顺序不一,你无法确定上面的模块是否创建,你又该如何扩展? 某个模块都需要引用一个变量又该怎么办?突然感觉到自己的渺小,太多的问题等待着我们来解决,但是一旦我们深入的研究得到一份完美的解决方案时,这将为我们的项目带来多少便利,节省我们许多的时间,可以不用加班,回家陪陪女朋友或者老婆小孩那该是多好。废话补多少了,我们来看看下面这种方式

四、Module模式

 1 var calculateMoney1 = (function(){...})();
 2 var calculateMoney2 = (function(cal, hasMoney){
 3     var _count = 25;
 4     var _prices = 3.4;
 5 
 6     function _cost(_count , _prices ){
 7          return _count*_prices;   
 8     }
 9     
10      cal.giveChange = function(){
11           return hasMoney-_cost(_count, _prices);
12     }        
13     return cal;
14 })(calculateMoney1 || {}, 100);

这种Module模式(module模式详见:汤姆大叔博客)的好处显而易见:

  1. 模块化,可重用
  2. 封装了变量和function,和全局的namaspace不接触,松耦合
  3. 只暴露可用public的方法,其它私有方法全部隐藏

Module模式是目前我个人比较推荐,我在实际工作中,没有人教过我,我慢慢摸索到“对象写法”,后来看到大叔博客中提到的Moduel模式,欣喜若狂,感觉自己真是太菜了。

  至于javascript的模块化编程,上面只是提到一部分,还有些更加高级些的我也正在摸索,如:如果js文件存在依赖,如果确定需要依赖的模块已被加载?如何动态加载模块?等等。

 

 

posted @ 2013-12-11 20:56  塞菲罗斯  阅读(252)  评论(0编辑  收藏  举报