JavaScript模块化编程(1):模块的写法

声明:本文摘抄自 阮一峰 的博客,这位大神给我了很大的帮助,本文是为了加深自己对JavaScript理解而写的。

前言:

  javascript不再是一个简单的脚本语言了,现在 90%的程序员多多少少都用过这门语言。再则H5的发展和人们在能满足功能需求的基础上对着页面人性化的交互要求,web开发也日益复杂。而Javascript模块化编程,已经成为了一个迫切的需求。在理想的情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块。

  但是,Javascript 不是一种模块化编程语言,它不支持 “类”(class),更遑论“模块”(module)了,特此申明正在定制的 ECMAScript标准 第六版将正式支持 “类” 和 “模块”。它将Javascript 变成了真正的企业级语言,预计在2014年底发布!

  不过,Javascript 本身是一门弱类型的语言,所有,我们可以肆无忌惮的模仿任何其他语言所有的特性。(*^__^*) 嘻嘻……我喜欢

 

一,原始写法

  模块就是实现特定功能的一组方法。

  只要把不同的函数(以及记录状态的变量)简单的放在一起,就算一个模块。

 

function m1(){
   // code ...
}

function m2(){
  //code....  
}
View Code
  上面的函数 m1() 和 m2(),组成了模块,使用的时候,直接调用。
  这种做法缺点很明显:“污染” 了全局变量,无法保证不与其他的模块发生变量命名的冲突,而且,模块成员之间看不成有什么关系。
 
二,对象写法

  为了解决上面的缺点,可以把模块写成一个对象的模式,所有模块成员都放到对象里面。这样逻辑表达性就强了。

  

var module1 = new Object({
    _count:0,
    m1:function(){
        //code...
    },
    m2:function(){
        //code..
    }
});
View Code

  上面的函数 m1() 和 m2(),都封装在module1对象里面,使用时候,调用这个对象的属性就可以了。

  module1.m1();

  但是,这样写的方法会曝露所有模块成员,内部状态可以被外部改写。比如,外部代码可以直接改变内部计数器的值。

  module1._count = 5;

 

三,立即执行函数写法

  使用“立即执行函数写法”(Immediately - Invoked Function Expression, IIFE),可以达到不暴露私有成员的目的。

     

var module1 = (function(){
    
    var _count = 0;

    var m1 = function(){
        // code ...
    };

    var m2 = function(){
        //code..
    };

    return{
        m1:m1,
        m2:m2
    }
})();
View Code

  在此,我要对我的同事(YR)说声抱歉,我不应该对你说的这些有所怀疑,记得你刚说这个方式的时候,我还有所抵触,主要的原因在于,我们做的APP不是单页应用。现在看来要好好的向你学习。

  这个立即执行函数写法,说白了就是一个 闭包函数 赋值给一个变量,在闭包函数里有一个入口,可以返回接口给外部调用。

  使用上面的写法,外部函数就没有办法访问到内部私有属性,因为闭包本身就是有块级作用域。

console.log(module1._count) //undefined

  module1就是Javascript模块的基本写法,下面还有对这种写法进行加工。

 

四,放大模式

   如果一个模块很大,必须分成几个部分,或一个模块继承另一个模块,这时候必要采用“放大模式”(augmentation)

  

var module1 = (function(mod){
    mod.m3=function(){
        //code...
    };

    return mod;
})(module1)
View Code

  以上代码为module1模块添加一个新的方法 m3(),然后返回新的 module1模块。

     放大模式,感觉就是为已有的模块做延生,我们有时也会对 原生的 Arry对象做一些另外的延生方法。

 

五,宽放大模式(Loose augmentation)

  在浏览器环境中,模块的各个部分通常是从网上获取的(Jquery),有时无法知道哪个部分先会加载,如果采用上一节写法,第一个执行的部分可能加载一个不存在的空对象,会报错,这时候就要采用“宽放大模式”

 

var module1 = (function(mod){
    //code....
    return mod;
})(window.module1 || {})
View Code

  和放大模式相比较,“宽放大模式”就是 “立即执行函数”的参数可以是空对象。

  对此,我还没有碰到过,,不过这样写应该不会有问题,比较保险一点。

 

六,输入全局变量

  独立性是模块的重要特点,模块内部最好不要和程序其他部分直接交互。

  为了在模块内部调用全局变量,必须显式地将其他变量输入模块。

  

var module1 = (function(window,$){
    //code...
})(window,JQuery);
View Code

  上面的module1模块需要使用Jquery库和window,就把这两个库(其实是两个模块),当做参数输入 module1,这样保证了模块的独立性,还使得模块之间依赖关系变得明显。顺便说下,Jquery和一些框架都会采用该方式来编写的!

posted @ 2014-08-10 23:23  jienyi  阅读(139)  评论(0编辑  收藏  举报