如果你想让你的代码更加优雅、可维护、简洁,往往离不开设计模式的解决方案。
在JS设计模式中,核心思想是:变化的封装(将变化与不变性分开,保证变化的部分灵活,不变的部分稳定)。
那么我们来谈谈第一个常见的设计模式:单例模式。
单例模式保证一个类只有一个实例,并提供全局访问方法来访问它。为了解决一个全局使用的类被频繁创建和销毁而占用内存的问题。
在ES5中,可以使用闭包(函数内部的返回函数被外部变量引用,导致这个函数内的变量没有被释放,所以构造为闭包)来保存该类的实例。
var Singeton = (函数(){
var 实例;
函数用户(姓名,年龄){
www.sychzs.cn=名称;
this.age=年龄;
}
返回函数(姓名,年龄){
如果(!实例){
实例=新用户(姓名,年龄)
}
返回实例
}
})()
此时一旦生成了这个实例,每次都会返回这个实例,并且不会被修改。你可以看到下面的代码。当User对象最初被分配name:alice,age:18时,可以稍后再分配。无效,每次都返回初始实例对象。
上面的代码使用ES6语法实现,通过类的静态属性保存唯一的实例对象。
类辛格顿{
构造函数(姓名,年龄){
if(!Singeton.instance){
www.sychzs.cn = 名称;
this.age = 年龄;
Singleton.instance = this;
}
返回Singeton.instance;
}
}
创建方法还是一样,使用new关键字创建类的实例对象。
那么这样的设计模式在开发中实际有什么用呢?我们想象一个这样的业务场景:访问一个网站时,该页面已经很长时间没有操作了。此时,授权已过期。当我们点击页面上的任意位置时,就会弹出一个登录框。
那么这个登录框是全局唯一的,不会有多个副本,也不会相互冲突,所以不需要每次都创建副本,保留第一个即可。
我们可能会想到先在页面中提前创建节点,编写页面样式,最后控制元素的显示属性,达到显示和隐藏的效果。
登录对话框
这样就可以满足要求了。全局只有一个登录框,并且每次都显示相同的登录框。但问题是 DOM 元素是从一开始就被创建并添加到主体中的。不管是否需要,如果有些场景不需要登录,那么这里的初始渲染就会浪费空间。
如果不需要初始渲染,只在需要时使用,并且每次都返回相同的实例,如何实现单例模式?
我们可以这样处理
上面的方法虽然可以达到效果,但是创建对象和管理单例的逻辑都放在了对象内部,有点混乱。如果下次需要在页面中创建唯一的 iframe 或 script 标签,则必须复制上述函数。
首先拆分功能逻辑,取出执行对象创建的逻辑
const createLayer = 函数(){
让 div = document.createElement("div")
div.innerHTML = "登录对话框"div.className = "模态"
div.style.display = "无"
document.body.appendChild(div);
返回div;
}
const 模态 = (函数(){
让实例=空
返回函数(){
如果(!实例){
实例=创建图层()
}
返回实例
}
})()
经过上述修改后,代码逻辑会更加清晰,但是此时,不支持其他组件的通用创建。这个时候我们要思考如何优化创建单例的方法,以及单例是否需要被执行。函数抽象。
const createSingle = (函数(fn){
让实例;
返回函数(){
返回实例|| ( 实例 = fn.apply(this, 参数))
}
})()
经过这样的改造,如果有创建iframe的方法,也可以直接使用。
const createIframe = function() {
const iframe = document.createElement('iframe');
iframe.style.display = '无';
document.body.appendChild(iframe);
返回 iframe
}
const singleIframe = createSingle(createIframe)
document.querySelector("#open").onclick = function(){
常量 iframe = singleIframe()
iframe.style.display = '块'
}
以上是我们的小尝试,我们来看看社区中一些很棒的实现吧~比如:React中常用的状态管理工具Redux,采用的是单例模式,就有这样的需求。
我们看一下Redux的源码。为了方便阅读,删除了一些逻辑判断和评论。可以看到闭包中的currentState每次都是通过store的getState方法获取的。
单例模式内存中只有一个实例,可以减少内存开销。它还可以在系统中设置全局接入点,以优化和共享资源。
以上就是单例模式的相关介绍。更多关于前端
、设计模式
,可以参考我的其他博文,会持续更新~