单例模式的定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
传统面向类的单例模式实现
var Singleton = function (name) {
this.name = name;
this.instance = null;
}
Singleton.prototype.getName = function () {
alert(this.name)
}
Singleton.getInstance = function (name) {
if (!this.instance) {
this.instance = new Singleton(name)
}
return this.instance
}
var a = Singleton.getInstance('sven1');
var b = Singleton.getInstance('sven2');
alert( a===b ) //true
这种方式创建单例类和以往不同的是,以往使用new(…)来获取对象,而这里使用Singleton.getInstance(…)来获取对象。使用者要知道这是一个单例类。
JavaScript中的单例模式
在JavaScript中,会把全局变量当做单例模式来使用。比如:
var a = {}
通过这种方式创建的变量a是独一无二的,但是在JavaScript中全局变量会带来很多问题,尤其是要注意全局变量的污染。我们可以采用以下办法:
1 使用命名空间
var namespace1 = {
a: function(){.....},
b: function(){.....}
}
2 使用闭包封装私有变量
var user = (function () {
var _name = 'sven',
_age = 29;
return {
getUserInfo: function () {
return _name + '-' + _age
}
}
})();
惰性单例
有这样的需求:点击一个按钮后,弹出一个登陆框。很明显这个登录框在整个页面中是唯一的,在创建的时候我们要注意,只有当点击后才创建这个登录框,而且一旦创建,就不必要重复创建!
var createDiv = (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 = createDiv();
loginLayer.style.display = 'block';
}
这段代码中,我们使用了一个立即执行函数,立即执行函数的作用就是创建一个独立的函数作用域,避免变量的污染。立即函数执行后,返回了一个函数,在该函数中判断变量div是否为undefied,如果是的话,再创建。因此在点击事件的回调函数中,我们调用这个方法,只会创建唯一一个div。