zoukankan      html  css  js  c++  java
  • 设计模式-单例模式

    单例模式的定义:保证一个类仅有一个实例,并能够被全局访问。

    单例模式在开发中应用非常广泛,比如网站的登录浮窗,当我们单击登录按钮的时候,页面中会出现一个登录浮窗,这个登录浮窗是唯一的,无论单击多少次登录按钮,这个浮窗都只会被创建一次,那么这个登录浮窗就适合用单例模式来创建

    单例模式

    下面使用单例模式创建一个DIV节点

    // 用于创建DIV的类
    var CreateDiv = function(html) {
      this.html = html;
      this.init();
    };
    
    CreateDiv.prototype.init = function() {
      var div = document.createElement('div');
      div.innerHTML = this.html;
      document.body.appendChild(div);
    };
    
    // 确保实例唯一性
    var ProxySingletonCreateDiv = (function() {
      var instance;
      return function(html) {
        return instance || (instance = new CreateDiv(html));
      }
    })();
    
    // 测试
    var a = new ProxySingletonCreateDiv('sven1');
    var b = new ProxySingletonCreateDiv('sven2');
    console.log(a == b) // true
    

    无论实例化多少个ProxySingletonCreateDiv,最终都只创建一个div,这就是单例模式。CreateDiv用于实现逻辑操作,init方法是一个用于初始化的通用函数(根据实际业务场景),最后用一个闭包(ProxySingletonCreateDiv)保证实例的唯一性

    惰性单例

    惰性单例指的是在需要的时候才创建对象实例,这种技术在实际开发中非常有用。以登录浮窗为例,实现方式有两种:

    1. 在页面加载完成后创建好浮窗,然后隐藏,点击登录按钮时显示
    2. 在页面加载完成后浮窗未创建,第一次点击登录按钮时创建浮窗

    第二种方法的好处是,如果用户只是浏览网站,根本没打算登录,就可以少创建一个节点。

    前面的单例模式是接近传统面向对象语言的实现,即单例对象从“类”中创建而来,这在面向对象的语言中是一种较好的实现方式,但JS本身并不是面向对象的语言,使用类的方式实现意义不大。下面结合JS的风格实现登录浮窗惰性单例

    // 使用闭包,确保fn只会执行一次
    var getSingle = function(fn) {
      var result;
      return function() {
        return result || (result = fn.apply(this, arguments));
      }
    };
    
    // 创建浮窗函数
    var createSingleLoginLayer = getSingle(function() {
      var div = document.createElement('div');
      div.innerHTML = '我是登录浮窗';
      div.style.display = 'none';
      document.body.appendChild(div);
      return div;
    });
    
    document.getElementById('loginBtn').onclick = function() {
      var loginLayer = createSingleLoginLayer();
      loginLayer.style.display = 'block';
    };
    

    当用户首次点击登录按钮,createSingleLoginLayer函数会创建一个浮窗并显示,而后再点击时getSingle函数会判断是否已经创建过,确保只创建一次。这是一种通用的实现方式,比如在使用JSONP跨域时,会创建一个script标签,然后动态改变他的src值,只需要getSingle中的参数即可

    var createSingleScript = getSingle(function() {
      var script = document.createElement('script');
      document.body.appendChild(script);
      return script;
    });
    
    document.getElementById('getUserInfo').onclick = function() {
      var sc = createSingleScript();
      sc.src = 'https://test.com/api?callback=userinfo';
    };
    
    常用网站: SegmentFault | GitHub | 掘金社区
  • 相关阅读:
    PMAC运动程序例程(一)
    【译】移动王国的诱惑【经济学人】
    粒子生物学【经济学人】
    快到家了【经济学人】
    关于贝加莱Modbus通讯的总结
    关于贝加莱Modbus通讯的总结
    移动王国的诱惑【经济学人】
    什么是Modbus
    动物精神【经济学人】
    什么是Modbus
  • 原文地址:https://www.cnblogs.com/yesyes/p/15375955.html
Copyright © 2011-2022 走看看