-
定义一个模块
var Module = (function(){
var my = {}, //在末尾暴露出去的对象
privateVariable = 1; //模块内部私有变量
function privateMethod (){ //私有方法
//...
};my.modulePrototype = 1; //外部可调用的属性和方法 my.moduleMethod = function(){ //... }; return my; //将my暴露出去 })()
注意,我们声明了一个全局模块MODULE,有两个公开属性:方法MODULE.moduleMethod和属性MODULE.moduleProperty。而且,匿名函数的闭包还维持了私有内部状态。同时学会之上的内容,我们就很容易引入需要的全局变量,和输出到全局变量。
通过将匿名自执行函数的返回值赋给一个新的变量来将匿名函数内的方法和属性暴露出来,通过Module.modulePrototype,可Module.moduleMethod()来调用。
-
扩展模块
首先我们在扩充模块的文件内先引入模块(全局),给他添加属性,然后再输出他:var Module = (function(my){ my.anotherMethod = function(){ //给my添加一个方法 }; return my; })(Module)//将Module作为参数传入这个匿名自执行函数,给他添加一个新的方法之后再将my返回重新赋值给Module,注意前面的var,加不加无所谓
-
松耦合扩充
上面的例子有个不好的地方就是我们在扩充模块时,这个模块必须是已存在的,这样我们就必须在模块加载完成之后才可以给他添加一些方法。这样我们就无法做到异步加载,因此我们可以创建灵活多部分的模块,可以将他们无顺序加载,以松耦合扩充。每个文件应有如下的结构:
var Module = (function(my){
my.anotherMethod = function(){
//给my添加一个方法
};return my; })(Module || {})
这个模式里,var语句是必须的,以标记引入时不存在会创建。这意味着我们可以同时加载所有模块文件而不被阻塞。
-
紧耦合扩充
虽然松耦合可以异步加载,但是也会有一些劣势,最重要的,我们不能安全的覆盖模块属性(因为没有加载顺序)。紧耦合扩充意味着一组加载顺序,但是允许写覆盖:
var Module = (function (my)
{
var old_moduleMethod = my.moduleMethod;
my.moduleMethod = function(){
//method override,has access to old through old_moduleMethod
}return my; })(Module)
-
克隆和继承
var Module_Two = (function(old){
var my = {},
key;for(key in old){ if(old.hasOwnProperty(key)){ //只赋值自身属性,不复制原型属性 my[key] = old[key]; } } var super_moduleMethod = old.moduleMethod; my.module_NewMethod = function(){ //添加新方法 //override method on the clone,access to super through super_moduleMethod }; return my; })(Module);
这种方式也许最不灵活。他可以实现巧妙的组合,但是牺牲了灵活性。正如我写的,对象的属性或方法不是拷贝,而是一个对象的两个引用。修改一个会影响其他。这可能可以保持递归克隆对象的属性固定,但无法固定方法,除了带eval的方法。不过,我已经完整的包含了模块。(其实就是做了一次浅拷贝)。
后面看不懂先不抄了。。