保证一个类仅有一个实例,并提供一个访问它的全局访问点。设计模式
一个单一对象。好比页面中有一个登录按钮,点击后出现一个登录弹窗,而这个弹窗是惟一的,无论按钮点击几回,弹框只会被建立一次,那这个弹窗就适合单例模式
来建立。缓存
以上述应用场景为例markdown
const createLoginModal = (function() { let div; return function() { if (div) return div; div = document.createElement("div"); div.innerHTML = "我是弹窗"; div.style.display = "none"; document.body.appendChild(div); }; })(); document.getElementById("loginBtn").onclick = () => { const loginModal = createLoginModal(); loginModal.style.display = "block"; }; 复制代码
上面实现了一个可用的单例方法,可是无法通用。若是想再建立一个span
标签的话,几乎要把createLoginModal
照抄一遍。app
咱们须要把不变的部分(管理单例的逻辑)抽离出来,把建立对象的方法经过 fn
当成参数动态传入getSingle
函数:函数
function getSingle (fn) { let result return function() { if (result) return result result = fn.apply(this, arguments) return result } 复制代码
接下来用来建立弹窗的方法能够用参数fn
的形式传入getSingle
。代码以下:oop
const createLoginModal = function() { const div = document.createElement("div"); div.innerHTML = "我是弹窗"; div.style.display = "none"; document.body.appendChild(div); return div; }; const createSingleLoginModal = getSingle(createLoginModal); document.getElementById("loginBtn").onclick = () => { const loginModal = createSingleLoginModal(); loginModal.style.display = "block"; }; 复制代码
单例模式禁止经过除了特殊构建方法之外的任何方式来建立自身类对象。 该方法能够建立一个新对象,但若是该对象已经被建立,则返回已有的对象。this
单例模式与全局变量不一样,它保证类只存在一个实例。 除了单例类本身之外,没法经过任何方式替换缓存的实例。spa