JavaScript设计模式之单例模式-惰性单例实现

目录

 

1.定义

2.全局变量与减少命名污染

使用命名空间

使用闭包封装私有变量

3.通用的惰性单例

将管理代理的逻辑封装成函数

使用例子(点击按钮才生成登录弹窗并显示)

使用例子(列表渲染只绑定一次事件)


1.定义

单例模式的定义是:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

2.全局变量与减少命名污染

全局变量不是单例模式,但在JavaScript开发中,我们经常会把全局变量当成单例来使用。例如:

var a = {}; 

a既是独一无二也可以全局访问,满足单例模式定义;但全局变量容易造成命名污染,大项目开发时随时有可能被别人覆盖。所以要用以下俩种方式相对降低全局变量带来的命名污染:        

  • 使用命名空间

    var namespace1 = { 
        a: function(){
             alert (1);
        },
        b: function(){
            alert (2);
        }
    };

把a和b都定义为namespace1的属性,这样可以减少变量和全局作用域打交道的机会。

  • 使用闭包封装私有变量

    var user = (function () {
        var __name = 'xxx',
            __age = 21;
        return {
            getUserInfo: function () {
                return __name + '-' + __age;
            }
        }
    })();

我们用下划线来约定私有变量__name和__age,它们被封装在闭包产生的作用域中,外部是访问不到这两个变量的,这就避免了对全局的命令污染。

3.通用的惰性单例

惰性单例指的是在需要的时候才创建对象实例。

  • 将管理代理的逻辑封装成函数

    function getSingle(fn) {
        var result; // 在闭包中不销毁
        return function () {
            // 如果result被赋值,则返回;没有则执行创建方法
            return result || (result = fn.apply(this, arguments));
        }
    }
  • 使用例子(点击按钮才生成登录弹窗并显示)

    // 1.声明创建方法
    var createLoginLayer = function () {
        var div = document.createElement('div');
        div.innerHTML = '我是登录弹窗';
        div.style.display = 'none';
        document.body.appendChild(div);
        return div;
    }
    // 2.传入创建方法返回单例方法,还没创建
    var createSingleLoginLayer = getSingle(createLoginLayer);
    // 3.在需要的时候创建
    document.getElementById('loginBtn').onclick = function () {
        var loginLayer = createSingleLoginLayer();
        loginLayer.style.display = 'block';
    }
  • 使用例子(列表渲染只绑定一次事件)

    var bindEvent = getSingle(function () {
        document.getElementById('div1').onclick = function name() {
            alert('click');
        }
        return true; // 返回true是为了让单例方法不执行||后的创建
    })
    var render = function () {
        console.log('开始渲染列表');
        bindEvent();
    }
    render();
    render();
    render();
    // render函数和bindEvent函数都分别执行了3次,但div实际上只被绑定了一个事件

    注:以上参考《JavaScript设计模式与开发实践》的摘录笔记,强烈建议大家阅读原书!

猜你喜欢

转载自blog.csdn.net/qq_39287602/article/details/108724804