Introduction
在这篇文章里面,我们将会讨论在javascript里面最出名的编写代码方式module pattern
module pattern (模式模型)非常的出名在javascript的世界里,她帮助我们编写干净的基于javascript对象
module pattern限制开发者去创造很多的全局变量,他总是对于去编写较少的全局变量并且性能优异的web app有很大的帮助。
因此,这个模式提升了你网站的表现同时让网站也比较容易维护。
What is Module Pattern
在js中,函数能被用作一个模型,一些时候我们被要求去创建一个单独的实例对象而不是创建一类对象。
在这个module里面,里面的函数用于一个作用域链能够访问在较外面函数里面定义的变量和函数。
基于javascript编写的较大的应用程序,一般来说都是一个实例对象,他们全是被编写-使用module pattern
在一个module里面,所有定义的变量只在这里面是可见的,module 里面的方法能用于访问这些变量,因此这些方法被称作特权方法
因此,通过创建一个能够返回由对象字面量创建的对象里面拥有一个特权方法的匿名函数,还有因为闭包的原则,这些特权方法有权利访问匿名函数里面的变量和函数,我们称这样的创建模式为module pattern
Privileged Method
在module pattern 里面你可以创建私有变量和私有方法,这些东西你不想让外面的代码访问,与此同时呢,你可以创建一个公共的特权的方法,非常有用的是,你可以通过你创建的特权方法,来访问那些私有变量和函数。
Closure
为了学习module pattern 你必须掌握闭包原则,只有使用闭包才能够使你module pattern 变得强大和有用。
闭包说的就是,内部函数在一个父函数里能够访问其他的内部函数变量,即便这个父函数已经运行完毕。在module pattern 里面这个特权方法就是这样的存在。
Self-executed Function
在module pattern 我们通过自动执行的匿名函数创建唯一的全局变量,自动执行的匿名函数是一个匿名的方法通过被自己调用的类型,在下面的栗子:如何编写自动执行的匿名函数。
(function(){
//creat variable
//var name="nike";
//creat method
//var sayName=function(){};
})();//calling this method
在上面的代码中,只有一个匿名函数被声明,刚被声明就被调用通过编写();代码,这样这个匿名函数被自己立马调用,这就是自我之行的函数方法。
Sample of module pattern
//single Global Variable “Module”
var Module=(function(){
var privateVariable="some value",
privateMethod=function(){//do something};
//通过返回一个对象字面量,将能够通过变量访问特权方法
return{
//在被返回的对象里面通过调用特权方法,能够访问私有变量和方法
privilegeMethod:function(){
//这个方法有权访问私有变量和函数通过闭包原则
alert(privateVariable);
//访问私有变量
privateMethod();
//调用私有方法
}
};
})();
在上面的代码中Module是一个全局变量,通过声明调用,我们将一个匿名方法赋予变量。
现在我们可以调用特权方法通过编写Module.privilegeMethod(),特权方法可以访问私有变量和方法。如果有什么数据或者方法不想被外界知道可以编写到私有变量方法里面。
还可以以另外一种方式来编写,请看下面:
var Module=(function(){
var privateVariable="some value",
privateMethod=function(){},
retObject={
privilegeMethod:function(){
alert(privateVariable);
privateMethod();
}
};
return retObject;
})();
公众的方式是没有办法访问私有变量的和私有方法的,只有通过特权方法能够访问,因为闭包。
举个栗子:
var SeachEngine=(function(){
var luckyAlgo=function(){
return Math.floor(Math.random()*11);
}
return{
getYourLuckyNumber:function(){
return luckyAlgo();
}
}
})();
alert(SeachEngine.getYourLuckyNumber());
在上面的代码中,有一个全局变量SeachEngine,一个匿名自我执行函数被赋予这个变量,SeachEngine有一个私有方法--luckyAlgo和一个特权方法getYourLuckyNumber,这个特权方法被包裹在一个匿名对象字面量里面被返回,要想访问这个变量内部,只有一个方法,利用闭包通过特权方法调用私有方法返回一个随机数。
Creat Sub Modules
我们可以创建一个子模块来增加我们的模块对象:
SeachEngine.subSeach=(function(){
var defaultColor="Orange";
var myColorAlgo=function(num){
switch(num){
case 1:
defaultColor="Green";break;
case 2:
defaultColor="Green";break;
case 3:
defaultColor="red";break;
case 4:
defaultColor="Green";break;
case 5:
defaultColor="balck";break;
case 6:
defaultColor="Green";break;
case 7:
defaultColor="yellow";break;
case 8:
defaultColor="Green";break;
case 9:
defaultColor="white";break;
}
};
return {
getYourLuckyColor:function(){
myColorAlgo(SeachEngine.getYourLuckyNumber());
return defaultColor;
}
};
})();
在上面的例子中如果我们调用
getYourLuckyColor这个方法,那么将会返回一个基于随机数的颜色
alert(SeachEngine.subSeach.getYourLuckyColor());
Extending Modules
我们能够扩展已经存在的modules通过把他包裹在一个新的modules,这样做我们就能够访问,重写已经存在的modules中的方法,看下面的代码:
var Module1=(function(oldModule){
//将旧的modules赋予一个本地变量
var parent=oldModule;
//重写已经存在的特权方法
parent.privilegeMethod=function(){
//do sth different by overriding the old method
};
//新的私有方法访问以前的特权方法
var privateMethod2=function(){
parent.privilegeMethod();
parent.publicMethod1();
}
return{
newMethod:function(){
//do sth for this brand new module
}
};
})(Module);//Module object is the existing module that i want to extent
在上面的例子中,我们演示了关于module pattern新的特性,我们可以重新使用已经存在的module通过扩展,重写
我们将已经存在的旧的module 对象作为参数传入新建的module pattern ,然后将其赋予到一个本地的变量里面被称作parent,现在我们可以访问原有parent的私有和特权方法
总结:
我们给出了一些简单的例子,但是你可以学习然后创建复杂的代码。