JavaScript设计模式——单例模式

259 阅读1分钟

单例模式的组成

由普通类和代理类两个部分组成

  • 普通类 CreateDiv,创建div并添加到body中
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) {
    if (!instance) {
      instance = new CreateDiv(html);
    }
    return instance;
  };
})();

最终效果

var d2 = new ProxySingletonCreateDiv('d2');
var d1 = new ProxySingletonCreateDiv('d1');

页面上只有一个div(d2)

惰性单例模式

登录框通常只有一个,且第一次点击登录的时候创建。

<button id="loginBtn">登录</button>
<script>
  var createLoginLayer = function () {
    var div = document.createElement('div');
    div.innerHTML = '我是登录框';
    div.style.display = 'none';
    document.body.appendChild(div);
    return div;
  };

  var getSingle = function (fn) {
    var instance;
    return function () {
      if (!instance) {
        instance = fn.apply(this, arguments);
      }
      return instance;
    };
  };

  var createSingleLoginLayer = getSingle(createLoginLayer);

  document.getElementById('loginBtn').onclick = function () {
    loginLayer = createSingleLoginLayer();
    loginLayer.style.display = 'block';
  };
</script>

应用例子 - 实现jQuery的one方法

即元素绑定的方法值运行一次

<button>只打印一次log</button>
function getSingle(fn) {
  var instance;

  return function () {
    return instance || (instance = fn.apply(this, arguments));
  };
}

function logBtn() {
  console.log('点击一次btn');
  return true;
}

var onceLog = getSingle(logBtn);

document.querySelector('button').onclick = () => {
  onceLog();
};