一.单例模式的作用
单件模式经常被用来管理资源敏感的对象,比如:数据库连接对象、注册表对象、线程池对象等等,这种对象如果同时存在多个的话就会造成各种不一致的麻烦(你总不希望发生数据库重复连接的异常吧)
引自黯羽轻扬:设计模式之单件模式(Singleton Pattern)
此外,单例模式还可以用来减少内存开销(保证巨大对象只有一个)
二.最简单的单例模式
var singleton = {
// attr: val
}
嗯,就这么简单。singleton
指向的对象是唯一的,无法通过其它方式创建这样一个对象(深拷贝不算,因为拷贝的前提是已经存在一个这样的对象)。比起构造函数方式实现的单例,对象字面量有着天然的优势——它是“一次性”的
这种单例存在强依赖(紧耦合)的缺点,依赖关系被限制在对象字面量中,甚至都没有办法在初始化时传参(单例本身是一个功能完整的对象(模块),如果无法在初始化时传参,势必会影响其功能)
三.一般单例模式
可以结合模块模式来修复上面的问题,例如:
var singleton = (function() {
var obj; // 单例的引用
function init() {
// 私有属性
// var attr = val
return {
// 公有属性
// attr: val
}
}
return {
getInstance: function() {
if (!obj) {
obj = init();
}
return obj;
}
}
})();
// 使用
var mySingleton = singleton.getInstance();
// mySingleton.xxx
singleton.getInstance()
就是全局访问入口,从这个入口拿到的对象都是同一个。如果不需要延迟初始化,就不需要提供getInstance
接口了,直接返回单例对象即可。当然,在大多数时候,单例模式意味着巨大对象,延迟初始化是很必要的
四.JavaScript中单例模式的作用
浏览器环境中的JS是单线程的,不需要管理临界资源,而且也不存在资源敏感的大对象(数据库连接对象、注册表对象、线程池对象等等)。这样看来,JS中单例模式好像没什么用。
事实确实是这样,JS中单例模式唯一的用途可能就是管理巨大对象了,避免同时存在多个巨大对象的内存消耗,比如jQuery这样的顶级命名空间,以及各级子命名空间,用单例模式来管理可以避免混乱
参考资料
《JavaScript设计模式》