单例模式的组成
由普通类和代理类两个部分组成
- 普通类 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();
};