理解JavaScript模块模式

javascript模块模式原先是由yahoo的douglas crockford提出的,在yahoo的博文中有关于此模式的描述(http://yuiblog.com/blog/2007/06/12/module-pattern/),这种模式也应用到了yui组件开发中,最核心的理念是用javascript的”类”封装私有和公有的属性和方法。

这种模式是javascript实现中的一种最佳实践方式.能够清晰地表达javascript面向对象概念 。它不允许开发人员定义全局变量去”污染”全局对象。通过增强这种模式,可以提高web的性能,同时这种模式实现的javascript代码也是易于维护的。

在javascript程序设计语言中,函数可以作为一个模块,在某些情况下,需要创建的是单例对象,而不是创建一个类的实例。在模块的内部,公共接口可以访问模块中的私有变量以及私有方法。这些公共接口函数又叫做特权方法(privileged methods)

许多javascript实现的应用程序使用的都是单例,因此javascript模块模式应用得就比较多。因此,创建一个匿名函数用来返回一个字面量对象包装的特权方法集,由于闭包原则,这些特权方法有权访问到匿名函数中的变量已经方法,这就是模块模式。

为什么使用模块模式?

1. 通过此模式可以把面向对象的一些理念在javascript语言中表述得更清晰,比如封装的思想。

2. 通过特权方法可以访问到私有变量以及私有方法,因为你不希望这些私有变量以及方法被外部无限制地访问。

使用此模式时需要注意的就是闭包的实现,即返回的特权方法。

自执行函数

在模块模式中,通过自执行方法来创建全局单例对象,通常创建的单例对象都是全局的。自执行方法通常用来创建匿名函数的。看一个例子:

(function(){

//函数体的实现

})();

理解了上面的自执行函数后,下面看一下模块模式

var jsmodule = function(){//全局单例对象

var privatevar = "foo";

var privatemethod = function(){

return privatevar;

};

return {

printvar: function(){

return privatemethod();

}

};

}();//自执行函数

console.log(jsmodule.printvar());

也可以这样:

var jsmodule = function(){

var privatevar = "foo";

var privatemethod = function(){

return privatevar;

};

var obj ={//注意这里的字面量对象可以是通过工厂模式创建的对象

printvar: function(){

return privatemethod();

}

};

obj.appendbar = function(){//对返回的对象进行扩展。

return "bar";

}

return obj;

}();

console.log(jsmodule.printvar());//foo

console.log(jsmodule.appendbar());//bar

创建子模块

在原有模块基础上加强模块功能

var jsmodule = (function(){

var privatevar = "foo";

var privatemethod = function(){

return privatevar;

}

return {

printvar: function(){

return privatemethod();

}

}

})();

jsmodule.submodule = function(){//在现有模块基础上添加子模块,相当于给一个字面量对象添加一个属性,这个属性值还是一个字面量对象

var anotherprivatevar = "bar";

var sayword = function(str){

switch(str)

{

case "foo":

return "foo bar";

default:

return "hello world";

}

};

return {

say: function(){

return sayword(jsmodule.printvar());

}

}

}();

console.log(jsmodule.submodule.say());

扩展模块

通过把现有模块包装到一个新的模块来扩展现有模块。可以访问现有模块中的方法,以及重写现有模块方法:

var newjsmodule = function(super_module){

var parent_module = super_module;//下面就可以访问父模块特权方法了

parent_module.printvar = function(){//重写父模块方法

return "bar";

};

var privatemethod2 = function(){

return "hello javascript";

};

return {

newprintvar: function(){

return parent_module.printvar();//访问父模块方法

}

}

}(jsmodule);//通过传递已有模块来扩展该模块,定义完匿名函数就立刻执行

console.log(newjsmodule.newprintvar());

模块模式的缺点

如果想改变属性和方法的可见性,那么就要修改每一处使用到这些属性以及方法的地方

在模块后来添加的方法中无法访问到原模块中的私有属性以及方法,可以通过创建子模块或者扩展模块来扩展功能。

var jsmodule = function(){

var privatevar = "foo";

var privatemethod = function(){

return privatevar;

};

return {

printvar: function(){

return privatemethod();

}

};

}();

console.log(jsmodule.printvar());

jsmodule.newmethod = function(){

return privatemethod();referenceerror, privatemethod is not defined()

}

console.log(jsmodule.newmethod());

小结

没有完美的解决方案,只有合适的。通过对象模式可以写出大型复杂的javascript程序,yui的开发都用到此模式,所以在平时的开发中还是值得借鉴的。


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值