单例模式
用于改善代码结构的最简单 的技术就是使用精心选择的命名空间,通常这一模式被称为单例。以下是我比较喜欢的书写格式:
var myApp={
init:function(){
var self=this;
self.getData();
self.eventBlind();
//单例的初始化代码
},
eventBlind:function(){
var self=this;
//单例中所有的事件委托代码
},
getData:function(){
var self=this;
//单例的同步数据请求代码,用于渲染模版引擎
}
}
//通过ready()函数调用
$(document).ready(myApp.init);
单例模式允许多个开发人员跨越多个文件,在单个应用程序名称空间之下进行工作,而且可维护性好、减少了开发人员相互踩脚趾的机会。但是这么多单例的命名是一个问题,而且代码很可能冗余,在开发庞大的javascript文件的团队中不可取。优化方案是,把网站的每一个主要的部分拆分为一个独立的js文件,common部分掌握在项目主管手里,其他部分分给每个成员,最后把一个页面的多个js文件压缩和并为一个。
Module模式
Module模式又叫模块模式,是单例模式的一个变种,它增强了单例模式提供的封装性,并增加了创建私有方法和私有属性的功能。模块模式包含三个主要的组件:一个与前面例子类似的命名空间、一个立即执行的函数和函数的返回对象,该返回对象中包含了公有方法和公有属性。
//app的命名空间。传入jQuery对象以缩短查找过程
var myApp=function($){
//私有变量和方法,仅在该myApp中可用
var message="not directly accessible from outside the module";
function multiplier(x,y){
return x*y;
}
//返回对象包含了公有属性和公有方法
return{
init:function(){
//初始化app
},
prop:'42',
specialNumber:function(){
//访问私有方法
var num=multiplier(7,6);
return "Our special number is definitely"+num;
},
//对私有变量的提供有控制的访问
shareMessage:function(arg){
if(arg==="open sesame"){
return message+",unless you know the magic word";
}else{
throw new Error("You need to know the magic word");
}
}
};
}(jQuery);
扩展该模式以增加更多的模块非常简单,如下面的例子。如果你对面向对象语言诸如c#、Java比较了解,那么一定对private、public关键字的使用非常熟悉,javascript的module模式提供了与之类似的功能。当然,javascript开发中并非都需要使用这种受保护的访问,但当我们在开发大型的需要安全性控制的业务中此模式非常有用。面向对象是一种更高级的编程思想,运用它有条理地解决问题对我们本身也是一种提升。
myApp.dashboard=function($){
//私有变量和方法
var config={
"color":"blue",
"title":"my dashboard",
"width":"960px"
};
return{
init:function(){
//初始化 dashboard
},
//updateConfig 方法允许更新私有config对象的配置
updateConfig:function(obj){
if($.inArray(obj.color,["red","blue","green","purple"]!==-1))
{
config.color=obj.color;
}
config.title=obj.title || config.obj;
config.width=obj.width || config.width;
},
render:function(){
//呈现dashboard
var $dashboard=$("<div/>").html("<h1/>");
$dashboard.text(config.title).css({
"Width":config.width,
"color":config.color
});
$("main").append($dashboard);
}
};
}(jQuery);