前面所讲的单例模式又一个共同点:单例对象都是在脚本加载时被创建出来。对于资源密集的或配置开销甚大的单例,更合理的做法是将其实例化推迟到需要使用他的时候。
这种技术就是惰性加载(lazy loading)。
实现步骤如下:
1).将所有代码移到constructor方法中
2).全权控制调用时机(正是getInstance所要做的)
XGP.lazyLoading = (function(){ var uniqInstance; function constructor(){ var attr = false; function method(){ } return { attrp: true, methodp: function(){ } } } return { getInstance: function(){ if(!uniqInstance){ uniqInstance = constructor(); } return uniqInstance; } } })();
6、分支技术
分支是一种用来把浏览器间的差异封装在运行期间进行设置的动态方法中的技术。
// 分支单例 (判断程序的分支 <浏览器差异的检测>) var Ext = {} ; var def = false ; Ext.More = (function(){ var objA = { // 火狐浏览器 内部的一些配置 attr1:'FF属性1' // 属性1 // 属性2 // 方法1 // 方法2 } ; var objB = { // IE浏览器 内部的一些配置 attr1:'IE属性1' // 属性1 // 属性2 // 方法1 // 方法2 } ; return (def) ?objA:objB; })(); alert(Ext.More.attr1);
比如说,如果网站中要频繁使用xhr,每次调用都要再次运行浏览器嗅探代码,这样会严重缺乏效率。更有效的做法是在脚本加载时一次性地确定针对浏览器的代码。这正是分支技术所做的事情。当然,分支技术并不总是更高效的选择,在两个或者多个分支中只有一个分支被用到了,其他分支就占用了内存。
在考虑是否使用分支技术的时候,必须在缩短时间和占用更多内存这一利一弊之间权衡一下。
下面利用分支技术实现XHR:
var XHR = (function(){ var standard = { createXhrObj: function(){ return new XMLHttpRequest(); } }; var activeXNew = { createXhrObj: function(){ return new ActiveXObject('Msxml2.XMLHTTP'); } }; var activeXOld = { createXhrObj: function(){ return new ActiveXObject('Microsoft.XMLHTTP'); } }; var testObj; try{ testObj = standard.createXhrObj(); return testObj; }catch(e){ try{ testObj = activeXNew.createXhrObj(); return testObj; }catch(e){ try{ testObj = activeXOld.createXhrObj(); return testObj; }catch(e){ throw new Error('No XHR object found in this environment.'); } } } })();
7、单例模式的弊端
了解了这么多关于单例的知识,我们再来看看它的弊端。
由于单例模式提供的是一种单点访问,所以它有可能导致模块间的强耦合。因此也就不利于单元测试了。
综上,单例还是留给定义命名空间和实现分支型方法这些用途。
通过七点不同方面对单例模式的介绍,大家是不是对单例模式有了更深入的了解,希望这篇文章可以帮到大家。
您可能感兴趣的文章: