一、 模块模式介绍
随着网页越来越像桌面程序的大流,Javascript模块化编程已经成为了一个迫切的需求。所谓模块, 就是实现特定功能的一组方法。C++,Java等语言对模块化的实现表现在给类提供私有和公共封装。由于Javascript不支持“类”,因此它需要基于闭包的特性,使用“模块模式”的设计模式,来实现Javascript的模块化编程。
以下是实现模块化的方法:
1.1 原始写法
function m1 { // ...... } function m2 { // ...... }
缺点: 污染全局命名空间;可能与其他模块有命名冲突,难以看出模块成员之间的关系
1.2 对象写法
var module = { count: 0, m1: function() { // ...... }, m2: function() { // ....... } };
缺点:暴露所有模块成员
1.3 立即执行函数写法
var module1 = (function(){ var _count = 0; var m1 = function(){ //... }; var m2 = function(){ //... }; return { m1 : m1, m2 : m2 }; })();
在Javascript中,private是作为保留字,而不是关键字,即Javascript没有私有化这一功能。但Javascript的闭包使之可以模拟这一功能。
在以上代码中,匿名函数并未返回操作_count的接口, 因此_count作为私有属性只可被匿名函数内部声明的函数和语句操作。m1, m2的函数引用被返回给module1,因此可被外界访问。
使用立即函数执行法可以对外界提供公共属性和方法的同时,保护内部私有属性和方法。
二、更高级的模块模式
2.1 扩展性
Javascript中的模板可被划分为多个文件。以下例子对上面的module进行扩展。
var module1= (function (my) { my.anotherFun = function () { // do someting... }; return my; }(module1||{})); // {}保证当module1未被创建过时,建立空对象
每个扩展的module都有自己独立的私有属性,方法。
2.2 跨文件私有属性共享
每个文件的module都只保持自己的私有状态,无法访问其他文件的私有属性。以下是解决多文件私有属性共享的一个方法:
var module= (function () { //将所有的私有属性、方法都定义在_private对象中 //每个扩展Module都可以通过my._private来访问 var my = {}, _private = my._private = {}, _seal = function (){ //密封,删除所有私有数据的可访问性 delete my._private; }, _unseal = function (){ //解封,让私有数据重新可访问 my._private = _private; }; my.extend = function(otherModules){ //必须通过此方法来添加扩展Module文件 _unseal(); //add other modules _seal();//异步调用,此处只是示意,真正的代码并非如此 } return my; }());
上面的module需要被第一个加载,然后利用module.extends来加载其他的扩展。
3. 输入全局变量
独立性是模块的重要特点,模块内部最好不要与程序的其他部分直接交互。因此为了在模块中调用全局变量,必须显示地将外部变量传入模块,以保证独立性。
var module = (function($, YAHOO) { // ...... })(jQuery, YAHOO);
参考:
http://www.cnblogs.com/Darren_code/archive/2011/08/31/JavascripDesignPatterns.html
http://www.ruanyifeng.com/blog/2012/10/javascript_module.html