javascript实现模块的几种方法:

  • 对象字面量表示法

  • Module模式

  • AMD模式

  • CommonJS模式

  • ECMAScript Harmony模块

1. 对象字面量

/*1.对象字面量型*/
var myObjectLiteral = {

    variableKey: variableValue,

    functionKey: function(){

    }
}

//完整版
var myModule = {

    myProperty: "someValue",

    //配置对象
    myConfig: {
        useCaching: true,
        language: "zh-cn"
    },

    //基本方法
    myMethod: function(){
        //todo ..
    },

    //根据配置信息输出内容
    myMethod2: function(){
        console.log("caching is:"+(this.myConfig.useCaching)?"enabled":"disabeld");
    },

    //重写当前的配置信息
    myMethod3: function(newConfig){
        if(typeof newConfig === "object"){
            this.myConfig = newConfig;
            console.log(this.myConfig.language);
        }
    }


};

/*输出结果值*/
myModule.myMethod();
myModule.myMethod2();  //caching is enabled;
var config = {
    useCaching: false,
    language: "en"
}
myModule.myMethod3(config);  //en

2. Module模式

最初被定义为一种在传统软件工程中为类提供私有公有封装的方法。
方式: Module模式用于进一步模拟的概念,
好处: 能够使一个单独的对象拥有公有/私有方法和变量,从而屏蔽来自全局作用域的特殊部分
结果: 函数名与在页面上其他脚本定义的函数冲突的可能性降低

2.1 私有

只需要返回一个公有API,其他的一切都可以放在私有必包里。该模式返回一个对象。

var testModule = (function(){
     var counter = 0;
     
     return {
         incrementCounter: function(){
              return ++counter;
         },
         resetCounter: function(){ 
              console.log("value: "+counter);
              counter = 0;
         }
    }
})();
console.log(testModule);  //打印出来的结果是一个对象
//Object {} incrementCounter: () resetCounter: ()

testModule.incrementCounter();    //增加计数器
testModule.resetCounter();        //充值计数器

在上面的例子中,counter变量实际上完全与全局作用域隔离,进而表现的像一个私有变量。代码的其他部分无法直接读取incrementCounter()和resetCounter()。

包含命名空间,公有和私有变量的Module模式:

var myNamespace = (function(){
    var myPrivateVar = 0;
    var myPrivateMethod = function(foo){
        console.log(this+"/"+arguments.caller+"/"+arguments.callee);
        console.log(foo);
        console.log(myPrivateVar);
    };
    
    return {
         //公有变量
         myPublicVar: "foo",
         //调用私有变量和私有方法的公有函数
         myPublicFunction: function(bar){
              myPrivateVar++;
              myPrivateMethod(bar);
         }
    };
})();
console.log(myNamespace);
myNamespace.myPublicFunction("liuyidi");

2.2 使用Module模式实现一个购物车模块

var basketModule = (function(){
    //定义一个私有数组
    var basket = [];
    
    function doSomethingPrivate(){
       //...
    }
    
    function doSomethingElsePrivate(){
       //...
    }
    
    //返回一个暴露出的公有对象
    return {
       //添加item到购物车
       addItem: function(values){
          basket.push(values);
       },
       
       //从购物车删除item
       delItem: function(values){
          basket.pop(values);
       },
       
       //获取购物车里的item数
       getItemCount: function(){
          return basket.length;
       },
       
       //私有函数的公有形式别名
       doSomething: doSomethingPrivate,
       
       //获取购物车里所有item的价格总值
       getTotal: function(){
          var itemCount = this.getItemCount(),
              total = 0;
          while(itemCount--){
              total += basket[itemCount].price;
          }
          
          return total;
       }
    };    
})();
console.log(basketModule);
basketModule.addItem({item:"xs",price: 0.5});
basketModule.addItem({item:"bc",price: 0.6});
basketModule.addItem({item:"dj",price: 0.8});
console.log(basketModule.getItemCount());
console.log(basketModule.getTotal());
basketModule.delItem({item:"bc",price: 0.6});

(未完待续)

2.3 Module模式变化

2.3.1 引入混入

var myModule = (function($,_){
    
    function privateMethod1(){
        $(".container").html("test");
    }
    
    function privateMethod2(){
        console.log(_.min([10, 5, 100, 2, 1000]));
    }
    
    return {
        publicMethod: function(){
           privateMethod1();
        }
    }
})(jQuery,_);

2.3.2 引出

声明一个全局对象之后,再返回

var myModule = (function(){
   //模块对象
   var module = {},
       privateVar = "hello,world";
   
   function privateMethod(){
      //...
   }

   module.publicProperty = "Foobar";
   module.publicMethod = function(){
      console.log(privateVar);
   };

   return module;
})();

2.3.3 工具包和特定框架的Module模式实现

Dojo,ExtJS,YUI,jQuery


一流的人
696 声望12 粉丝

Front-End Web Engineer