单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点
使用场景:假设当我们点击登陆按钮的时候,页面中会出现一个登陆悬浮框,而这个登陆框是唯一的,无论单击多少次登陆按钮,这个框只会被创建一次。
实现思路:用一个变量来标志当前是否已经为某个类创建过对象,如果是,则在下一次获取该类的实例时,直接返回之前创建的对象
普通单例模式
var singleton = function(name){
his.name = name
}
singleton.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('seven1')
var b = singleton.getInstance('seven2')
console.log(a===b) // true
用代理实现单例模式
var proxySingletonCreateDiv = (function(){
var instance
return function(html){
if(!instance){
instance = new createDiv(html)
}
return instance
}
})()
var a1 = new proxySingletonCreateDiv('seven1')
var b1 = new proxySingletonCreateDiv('seven2')
console.log(a1===b1) //true
惰性单例模式
var createLoginLayer = (function(){
var div;
return function(){
if(!div){ //全局变量!判断div是否存在,存在即返回div,不存在便创建一个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'
}
通用的惰性单例模式:采用闭包的形式,将参数fn传入
var getSingle = function(fn){
var result; //使用result保存fn的结果,因为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 = getSingle(createLoginLayer);
document.getElementById('loginBtn').onclick=function(){
var loginLayer = createSingleLoginLayer();
loginLayer.style.display = 'block'
}
小结:单例模式的核心是确保只有一个实例,并提供全局访问,var 全局变量不是单例模式,但在JavaScript开发中可以把全局变量当成单例使用;闭包(一个函数内部的函数):可以读取函数内部的局部变量的函数,这些变量的值始终保持在内存中,出函数执行后,函数执行的作用域会被销毁,但活动对象不会被销毁。