浅析JavaScript单例模式(2)

<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单例模式介绍到此结束,有不对的地方请及时指出

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/9c4d6dfb17b4737bd64d94179cfea036.html