<html>
<body>
<button>登录</button>
</body>
<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>
</html>
上述方法,用一个变量来判断是否已经创建过登录浮窗,和上面上面实现单例的类的原理是一样的
4.通用的单例模式
如果在项目中用到了很多单例的情况,如果每个都做判断,其实是相当复杂的事情,但能不能写一个通用的方法,经过这个方法处理的就是单例的
<html>
<body>
<button>登录</button>
</body>
<script>
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 createMask = function() {
var div = document.createElement( 'div' );
div.innerHTML = 'mask';
div.style.display = 'none';
document.body.appendChild( div );
return div;
};
var createSingleLoginLayer = getSingle( createLoginLayer );
var createMask = getSingle( createMask );
document.getElementById( 'loginBtn' ).onclick = function(){
var loginLayer = createSingleLoginLayer();
var mask = createMask();
loginLayer.style.display = 'block';
mask.style.display = 'block';
};
</script>
</html>
我们发现在开发中并不会单独使用弹出窗,遮罩层和弹出窗是经常结合在一起使用,上面的方法就能使弹出窗和遮罩层都是单例的,其中核心的方法就是getSingle
在getSingle函数中,创建对象的方法 fn 被当成参数动态传入 getSingle 函数 ,result 变量因为身在闭包中,它永远不会被销毁。在将来的请求中,如果 result 已经被赋值,那么它将返回这个值 。
5. ES6中的单例模式
class SingletonApple {
constructor(name, creator, products) {
this.name = name;
this.creator = creator;
this.products = products;
}
//静态方法
static getInstance(name, creator, products) {
if(!this.instance) {
this.instance = new SingletonApple(name, creator, products);
}
return this.instance;
}
}
let appleCompany = SingletonApple.getInstance('苹果公司', '乔布斯', ['iPhone', 'iMac', 'iPad', 'iPod']);
ES6有类,也有静态方法,实现单例模式也显得非常的简单,学过Java的同学能看出几乎和Java的实现一模一样,直接调用SingletonApple的静态方法getInstance就能获得一个单例对象。ES6能不能直接new一个单例的对象出来呢,答案当然是可以的
class SingletonApple {
constructor(name, creator, products) {
this.name = name;
this.creator = creator;
this.products = products;
}
//静态方法
static getInstance(name, creator, products) {
if(!this.instance) {
this.instance = new SingletonApple(name, creator, products);
}
return this.instance;
}
}
JavaScript单例模式介绍到此结束,有不对的地方请及时指出