初涉JavaScript模式 (12) : 模块模式 【下】

即时函数

在上一篇中,我们搭起了一个简单的模块架子,但是在通常的场景下,我们会遇到一些问题,实例如下:

		//定义一个全局标识
		var GLOBAL = GLOBAL || {};
		//处理命名空间的函数
		GLOBAL.namespace = function(str) {
			var arr = str.split("."),
				o = GLOBAL;
			for (i = (arr[0] == "GLOBAL") ? 1 : 0; i < arr.length; i++) {
				o[arr[i]] = o[arr[i]] || {};
				o = o[arr[i]];
			}
		}
		//注册一个模块
		GLOBAL.namespace("Module");
		//字面量方式
		GLOBAL.Module.console = {
			msg : "WeiRan",
			log : function(){
				console.log(this.msg);
			}
		}
		GLOBAL.Module.console.log(); //WeiRan
		console.log(GLOBAL.Module.console.msg); //WeiRan
		//即时函数方式
		GLOBAL.Module.console1 = (function(){
			var msg = "WeiRan";
			return{
				log : function(){
					console.log(msg);
				}
			}
		}());
		GLOBAL.Module.console1.log(); //WeiRan
		console.log(GLOBAL.Module.console1.msg); //undefined 

在上面我列举了两种编写模块的方式,第一种字面量的形式完全不能保证私有属性,他的所有成员都是公开的,第二种,我们通过即时函数提供的私有作用域保证了模块私有成员的私有性,在最后返回对象了一个对象,该对象包含该模块的公共API。

而对于返回的对象,如果我们还要对公共API的具体实现逻辑也保持私有,那么使用揭示模块模式就再合适不过了。

揭示模块模式

揭示模块模式是对模块模式中私有性保护的升级,就拿我以前的一段代码为例,详细代码如下:

	GLOBAL.comm.comnav = (function() {
		var bindNav = function(navList) {
			$.each(navList, function(key, val) {
				$("#" + val.split("-")[0] + ">span").click(function() {
					$(this).siblings().each(function() {
						$(this).find(".active").hide().siblings().find("[_tag=" + $(this).attr("_tag") + "]").removeClass("red");
					});
					$(this).find(".active").show().siblings().find("[_tag=" + $(this).attr("_tag") + "]").addClass("red");
					showTag([val.split("-")[1], val.split("-")[2]], $(this).attr("_tag"));
				});
			});
		};
		var processNav = function(navId, commId, listId) {
			return navId + "-" + commId + "-" + listId;
		};
		var showTag = function(tagList, tagName) {
			$.each(tagList, function(index) {
				$("#" + tagList[index]).find("[_tag=" + tagName + "]").show().siblings().hide();
			});
		};
		return {
			init: bindNav,
			newInstantce: processNav
		}
	})();

在上面的示例中,我在模块内部定义了三个私有方法(注意是以函数表达式的形式定义的),我没有把API函数的具体逻辑显式的写在返回的对象中,我是以函数名的方式传递了一个私有方法的引用给API函数,这样我们就连模块暴露的API方法都进行了处理,这样才算真正的接口(只有声明,没有实现)

结语

这篇总结了下模块创建的方式,如果你在文中发现错误或则你觉得不正确的地方,希望你的指正。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。