JS设计模式--单例模式
单例模式
单例模式的定义是:保证一个类仅有一个实例,并提供一个访问它的全局访问。
JavaScript中的单例模式
JavaScript其实是一门无类语言,在开发中,经常把全局变量当成单例来使用。作为普通的开发者,我们有必要尽量减少全局变量的使用,即使需要,也要把它的污染降到最低。有以下两种方式可以相对降低全局变量带来的命名污染:
- 使用命名空间
适当地使用命名空间,可以减少全局变量的数量。最简单的方法是用对象字面量的方式:var namespace1 = { a: function(){ alert (1); }, b: function(){ alert (2); } };
- 使用闭包封装私有变量
这种方法把一些变量封装在闭包的内部,只暴露一些接口跟外界通信:var user = (function(){ var _name = 'sven', _age = 29; return { getUserInfo: function(){ return _name + '_' +_age; } } })();
惰性单例
惰性单例指的是在需要的时候才创建对象实例。
- JavaScript中的惰性单例实例一
在用户点击登录按钮的时候才开始创建该浮窗:<html> <body> <button id="loginBtn">登录</button> </body> </html> <script> var createLoginLayer = (function(){ var div; return function(){ if ( !div ){ div = document.createElement( 'div' ); div.innerHTML = "登录浮窗"; div.style.display = "none"; document.body.appendChild( div ); } return div; } })(); document.getElementById( 'loginBtn' ).onclick = function(){ var loginLayer = createLoginLayer(); loginLayer.style.display = 'block'; } </script>
- JavaScript中的惰性单例实例二
通用惰性单例,在上述的代码中,如果创建其他的节点,则需要将上述代码再复制一份,违反了单一职责原则,创建对象和管理单例的逻辑都放在createrLoginLayer对象内部。
现在我们把如何管理单例的逻辑从原来的代码中抽离出来,这些逻辑被封装在getSingle函数的内部,创建对象的方法fn被当成参数动态传入getSingle函数:
var getSingle = function( fn ){ var result; return function(){ return result || ( result = fn.apply( this, arguments ) ); } }; var createLoginLayer = function(){ var div = document.createElement( 'div' ); div.innerHTML = "我是登陆浮窗"; div.style.display = "none"; document.body.appendChild( div ); return div; }; var createSingleLoginLayer = getSing( createLoginLayer ); document.getElementById( 'loginBtn' ).onclick = function(){ var loginLayer = createSingleLoginLayer(); loginLayer.style.display = 'block'; }
- JavaScript中的惰性单例实例二
惰性单例小结
创建对象和管理单例的职责被分布在两个不同的方法中,这两个方法组合起来才具有单例模式的威力。