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