概念
单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。
核心:确保只有一个实例,并提供全局访问。
实现思路
一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常命名为getIntance
);当我们调用这个方法时,类持有的引用不为空则返回这个引用,如果为空须创建该类实例并将实例的引用赋予该类保持的引用;同时将该类的构造函数定义为私有方法,那么其他环境就无法通过调用该类的构造函数来实例化该类的对象,只能通过该类提供的静态方法得到该类唯一的实例。
实现 Java 语言中的单例模式
public class Singleton { private static final Singleton { private Singleton() { }; public static Singleton getInstance { if (INSTANCE == null) { synchronized(Singleton.class) { if(INSTANCE = null) { INSTANCE = new Singleton() } } } return INSTANCE; } } }
实现 JavaScript 语言中的单例模式
let Singleton = function(name){ this.name = name; } Singleton.prototype.getName = function() { console.log(this.name) } Singleton.getInstance = (function() { let instance; return function(name) { if(instance) return instance; return instance = new Singleton(name) } })() let s1 = Singleton.getInstance('owen'); // Singleton?{name: "owen"} let s2 = Singleton.getInstance('guowen'); // Singleton.getInstance('guowen'); s1 === s2 // true
JavaScript中单例作为一个命名空间提供者,从全局命名空间里提供一个唯一的访问点来访问该对象。
应用
命名空间
使用命名空间可以降低全局变量带来的命名污染;
最简单的方法是对象字面量
const globalWeb = { a() {},b() {} // ... }
或者使用闭包
let Singleton = (function(){ let instance; let init = function() { let name = 'owen'; return { name,data(){ return {} },method:{ } } } return { getInstance() { if(instance) return instance; return instance = init() } } }()) let app = Singleton.getInstance() // {name: "owen",data: ?,method: {…}}
惰性单例
惰性单例指在需要的时候才创建对象实例,在实现开发中非常有用,即目标对象只有在使用的时候才被创建,而不是页面加载好时创建。
模态框示例
点击一个按钮弹窗一个模态框,很明显页面是唯一的,一次不会弹窗多个模态框的情况
<!DOCTYPE html> <html lang="en"> <head> <Meta charset="UTF-8"> <Meta name="viewport" content="width=device-width,initial-scale=1.0"> <Meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>modal Box</title> <style> * { margin: 0; padding:0; } html{ width:100%; height:100%; } .Owen { width:30%; height:30%; margin:10% auto; } #modal { width:100%; height:100%; position:fixed; left:0; top:0; background: rgba(0,0.52); display:none; } .main{ width:30%; height:30%; margin:10% auto; text-align: center; background-color: #b0e8ff; } </style> </head> <body> <div class="Owen"> <button>Owen</button> </div> <div id="modal"> <div class="main"> <div> 我是弹框 </div> </div> </div> </body> <script> window.onload = function(){ let openModal = document.querySelector("button") let modal = document.querySelector("#modal") openModal.addEventListener('click',function(){ modal.style.display = 'block' }) } </script> </html>
第一种方法是在页面加载完成时创建好这个弹框,一开始就是隐藏的,只有点击按钮的时候才显示,这种方式有一个问题,就是我们进入页面,只是看看其他内容,不做任何操作;这样就造成资源浪费
<!DOCTYPE html> <html lang="en"> <head> <Meta charset="UTF-8"> <Meta name="viewport" content="width=device-width,0.52); } .main{ width:30%; height:30%; margin:10% auto; padding:20px; text-align: right; background-color: #b0e8ff; position:relative; } .main div { text-align: center; } .main span { display: inline-block; padding:5px; cursor:pointer; } </style> </head> <body> <div class="Owen"> <button>点我</button> </div> </body> <script> window.onload = function(){ init() } function init() { let openModal = document.querySelector("button") let createModal =( function() { let flag; // 生成 Modal 容器 let div = document.createElement('div') div.id = "modal" div.style.display = "none"; return function() { if(flag) return div; flag = true; let fra = document.createDocumentFragment(); // 添加 Modal 内容 els = `<div class="main"> <span class="close">×</span> <div> 我是弹框 </div> </div> ` div.innerHTML = els; fra.appendChild(div) document.body.appendChild(fra) // 关闭 Modal let close = document.querySelector('.close') close.addEventListener('click',function(){ flag = false; document.body.removeChild(div) }) return div } }()) // 显示 Modal openModal.addEventListener('click',function(){ createModal().style.display = "block"; }) } </script> </html>
第二种方法,只执行一次DOM的创建修改操作,不用频繁的创建和删除节点,提高资源利用率;
参考资料
《JavaScript设计模式与开发实践》
基维
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。