JavaScript 中的单态模式或称单例模式(singleton pattern),是指只有一个实例。常见的一些 JavaScript 框架例如 jQuery 和 YUI 等,应该就只有一个实例。
最简单的单态模式可以用对象来实现,例如:
var singleton = {
myvar: 'public variable',
myfun: function() {
return 'public function'
};
};
上述这种方法定义的属性和方法都是公有的,如果还需要有私有属性和方法,可以用函数来实现。例如:
var singleton = (function() {
// private members
var secret1 = '1+1=2';
var secfun1 = function() {
return 'private function 1';
};
// public members
return {
pubvar1 : 'public variable 1',
pubfun1 : function() {
return secret1;
}
};
})();
在 JavaScript 中,使用对象时内部的变量是无法直接隐藏的,而使用函数时内部的变量则无法永远保存。因此,上面的例子将两种方式结合起来,通过函数闭包来返回一个对象,以达到公私分明的效果。
如果还需要在 singleton 中继续增加方法,可以用下面的方式:
var singleton = (function(m) {
var secret2 = '2+2=4';
var secfun2 = function() {
return 'private function 2';
};
m.pubvar2 = 'public variable 2';
m.pubfun2 = function() {
return secret2;
};
return m;
})(singleton);
注意此时需要再用 var 关键字。其中的 secret2 属性只能被新增加的 getSecret2() 方法访问。
使用上面的方法,需要按照先后顺序来定义 singleton 的两个模块的内容。如果这两个模块的代码分别放在两个文件中,将不能并行加载它们。我们可以使用模块模式(module pattern),灵活地定义这两个模块而不用考虑其先后顺序。此时,我们只需要将前面的代码修改如下:
// these are in module1.js
var singleton = (function(m) {
var secret1 = '1+1=2';
var secfun1 = function() {
return 'private function 1';
};
m.pubvar1 = 'public variable 1';
m.pubfun1 = function() {
return secret1;
};
return m;
})(singleton || {});
// these are in module2.js
var singleton = (function(m) {
var secret2 = '2+2=4';
var secfun2 = function() {
return 'private function 2';
};
m.pubvar2 = 'public variable 2';
m.pubfun2 = function() {
return secret2;
};
return m;
})(singleton || {});
参考资料:
[1] Essential JavaScript Design Patterns
[2] JavaScript Module Pattern: In-Depth