单例模式

tech2024-11-08  5

什么是单例模式?

单例模式是只允许实例化一次的对象类,即一个类只有一个实例,可以作为命名空间管理,也可以用来管理静态变量,甚至可以说,某个模块无论创建多少次,只要在窗口中只能存在一个的这样的模块,都能用单例模式来封装。

封装在一个对象中,作为全局都可以使用:

var codeManager = { utils: { util1: function () {}, util2: function () {} }, doms: { create: function (domNode) { return document.createElement(domNode); }, remove: function (domNode, removeNode) { this.get(domNode).removeChild(this.get(removeNode)); }, get: function (id) {} }, ajax: { get: function (url, params, callback) {}, post: function (url, params, callback) {} } } // 使用 var fn = codeManager.doms.remove('id1', 'id2')

现在又有个场景,我要定义几个静态变量,但是js中没有静态变量定义的关键字,怎么办?

满足它能够被全局作用域访问的权限,但是没有修改的权限,用闭包实现 代码:

var static = (function () { var variables = { COUNT: 100, MAX: 1000, MIN: 1 } return { getStatic: function (name) { return variables[name] } } })() var count = static.getStatic('COUNT') // 100

小栗子

// 创建一个构造函数 var PromptComponent = function () { // 为了不让其反复被创建,把单例放在这里 this.createDom = this.singlePrompt(this.createPrompt); } // 初始化 PromptComponent.prototype.init = function (params) { var style = params.style || 'default', message = params.message || '提示!', duration = parseInt(params.duration) || 1500; // 创建dom,即弹出框 var promptDom = this.createDom(style, message); promptDom.style.display = 'block'; // 多少秒后自动隐藏 setTimeout(function () { promptDom.style.display = 'none'; }, duration) } // 控制弹出框只被创建一次 PromptComponent.prototype.singlePrompt = function (fn) { var instance; return function () { // 如果已经创建,则直接返回这个弹出框dom,否则新创建一个 return instance || (instance = fn.apply(this, arguments)); } } // 创建弹出框 PromptComponent.prototype.createPrompt = function (style, message) { var div = document.createElement('div'); var strHtml = '<p>'+ message +'</p><span class="prompt-close">×</span>' div.className = 'prompt ' + style; div.innerHTML = strHtml; div.style.display = 'none'; div.addEventListener('click', function () { div.style.display = 'none'; }, false) document.body.appendChild(div); return div; }

那么如何使用呢?继续看下面的代码

// 创建一个提示框实例 var warning = new PromptComponent(); document.getElementById('login').addEventListener('click', function () { // 利用Promise模拟登陆时的异步延迟 new Promise((resolve, reject) => { setTimeout(() => { resolve({code: 200}) }, 1000) }).then(res => { if (res.code == 200) { // 创建提示框 warning.init({ style: 'success', message: '登陆成功' }) } else { warning.init({ style: 'fail', message: '登陆失败' }) } }) }, false)

整个代码展示:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .prompt { position: fixed; top: 10px; left: 50%; transform: translateX(-50%); font-size: 18px; color: #ffffff; background-color: #df8263; border-radius: 3px; padding: 10px 30px; min-width: 100px; } .prompt p { padding: 0; margin: 0; } .prompt.default { background-color: #df8263; } .prompt.warning { background-color: #d9b131; } .prompt.success { background-color: #31d952; } .prompt.fail { background-color: #cab9b9; } .prompt-close { position: absolute; top: 50%; right: 10px; transform: translateY(-50%); width: 20px; height: 20px; display: flex; justify-content: center; align-items: center; cursor: pointer; } </style> </head> <body> <button id="login">登录</button> <script> var PromptComponent = function () { this.createDom = this.singlePrompt(this.createPrompt); } PromptComponent.prototype.init = function (params) { var style = params.style || 'default', message = params.message || '提示!', duration = parseInt(params.duration) || 1500; var promptDom = this.createDom(style, message); promptDom.style.display = 'block'; setTimeout(function () { promptDom.style.display = 'none'; }, duration) } PromptComponent.prototype.singlePrompt = function (fn) { var instance; return function () { return instance || (instance = fn.apply(this, arguments)); } } PromptComponent.prototype.createPrompt = function (style, message) { var div = document.createElement('div'); var strHtml = '<p>'+ message +'</p><span class="prompt-close">×</span>' div.className = 'prompt ' + style; div.innerHTML = strHtml; div.style.display = 'none'; div.addEventListener('click', function () { div.style.display = 'none'; }, false) document.body.appendChild(div); return div; } var warning = new PromptComponent(); document.getElementById('login').addEventListener('click', function () { new Promise((resolve, reject) => { setTimeout(() => { resolve({code: 200}) }, 1000) }).then(res => { if (res.code == 200) { warning.init({ style: 'success', message: '登陆成功' }) } else { warning.init({ style: 'fail', message: '登陆失败' }) } }) }, false) </script> </body> </html>
最新回复(0)