上次我们介绍了javascript的构造函数模式,今天介绍一下javascript中又一个常见的模式——模块化模式(module pattern)。
我们知道在javascript中一切都是对象,而对象有一种表示方式,成为字面量(literal notation),字面量就是在一个花括号中用逗号分隔开的一组键值对:
var person = {
name:"kesil",
age:20,
getName:function(){
console.log(this.name);
},
getAge:function(){
console.log(this.age);
}
}
这时候我们有一个全局的变量指向对象,我们可以通过.
操作符来使用对象中的变量和函数:
person.getName();
并且,只能在person中应用,在全局中直接使用里面的函数和变量是不行的。针对这个特性,我们可以用这种方式模拟我们在其他面向对象语言中看到的私有函数和共有函数(变量)。
var testModule = (function(){
var counter = 0;
return {
increamentCounter:function(){
return counter++;
},
resetCounter:function(){
counter = 0;
}
}
})();
我们通过立即执行一个匿名函数返回了一个对象,这个对象包含两个操作方法。我们的全局变量testModule指向返回的这个对象。这个时候都testModule
可见的就只有两个方法increamentCounter
和resetCounter
,也就是说我们通过全局变量testModule
只能访问increamentCounter
和resetCounter
。
参数引入:
在模块内部,我们希望使用外部定义的全局变量,我们不应该直接使用它们,因为这样会造成混乱。我们应该将它们作为参数传入模块内,如下例所示:
var myModule = (function(jQ){
function privateMethod1(){
jQ(".container").html("test");
}
function privateMethod2(){
console.log("hello");
}
return {
publicMethod:function(){
privateMethod1();
}
}
}(jQuery));
模块的扩展
以上的模块存在一个限制,就是一个模块的整体定义必须在一个文件中,但开发的时候是多个人,那么当有人想要对这个模块进行修改就会存在问题。这个问题的解决办法就是我们先引入原有模块,对模块进行添加等操作后再传出。
var myModule = (function(my){
my.anotherMethod = function(){
console.log("another");
}
return my;
}(myModule));
1.松耦合扩展:
现在我们可以对模块进行扩展了,但是上述方法的前提是模块已经存在,所以我们进行一个小小的修改抛弃这个前提:
var myModule = (function(my){
my.anotherMethod = function(){
console.log("another");
}
return my;
}(myModule || {}));
子模块:
想要实现子模块很简单,就是设置模块的一个属性为另外一个模块:
var myModule = (function(){
var privateDate = "2018.06.22";
function getPrivateData(){
return privateDate;
}
return {
publicMethod:getPrivateData()
}
})();
myModule.subModule = (function(){
var my = {
privateVal : 1,
getVal : function(){
return this.privateVal;
}
};
return my;
}());
console.log(myModule.subModule.getVal());
这就是常用的模块模式,如果其中有什么错误希望大家能指出。