当前位置: 首页 > Web前端 > HTML

JavaScript中的单例模式是这样使用的

时间:2023-03-28 00:33:20 HTML

如果你想让你的代码更优雅、更易维护、更简洁,往往离不开设计模式的解决方案。在JS设计模式中,核心思想:Encapsulatechange(将变化和不变性分开,保证变化的部分是灵活的,不变的部分是稳定的)。单例模式那么让我们来谈谈第一种常见的设计模式:单例模式。单例模式保证了一个类只有一个实例,并提供了一种全局的访问方式来访问它,以解决全局使用的类频繁创建和销毁占用内存的问题。ES5中使用闭包在ES5中可以使用闭包(函数内部的return函数被外部??变量引用,使得本函数中的变量无法释放,所以内置成闭包)来保存这个类的实例.varSingeton=(function(){varinstance;functionUser(name,age){this.name=name;this.age=age;}returnfunction(name,age){if(!instance){instance=newUser(name,age)}returninstance}})()这时候一旦生成这个实例,每次都会返回这个实例,不会被修改。可以看到如下代码,最初给User对象赋值时name:alice,age:18时,后面的赋值会失效,每次返回的都是初始实例对象。ES6使用类的静态属性上面的代码是使用ES6语法实现的,通过类的静态属性保存了唯一的实例对象。classSingeton{constructor(name,age){if(!Singeton.instance){this.name=name;这个。年龄=年龄;Singeton.instance=this;}返回Singeton.instance;}}创建方法还是一样,通过new关键字创建类的实例对象。案例那么这样的设计模式在开发中的实际用途是什么呢?我们想象这样一个业务场景:访问网站时,页面已经很久没有操作了,此时授权到期。当我们点击页面任意位置时,会弹出一个登录框。那么这个登录框是全局唯一的,不会有多个副本,也不会相互冲突,所以不用每次都创建一个,保留原来的就可以了。提前创建节点我们可能会想到先在页面上提前创建节点,写好页面样式,最后通过控制元素的display属性来实现显示和隐藏的效果。登录对话框

打开关闭这样就可以满足要求了。全局只有一个登录框,每次都显示同一个。但是问题是dom元素是从一开始就创建并添加到body中的,不管是否需要,如果有些场景不需要登录,那么这里的初始渲染会浪费空间。单例模式如果不需要初始渲染,只在需要的时候使用,每次都返回同一个实例的单例模式如何实现?我们可以这样处理虽然上面的方法可以达到效果,但是创建对象和管理单例对象的逻辑是放在对象内部的,有点混乱。而如果下次需要在页面中创建唯一的iframe或者script标签,就得重新复制??上面的函数。一般单例先拆分函数逻辑,取出创建对象的逻辑constcreateLayer=function(){letdiv=document.createElement("div")div.innerHTML="登录对话框"div.className="modal"div.style.display="无"document.body.appendChild(div);returndiv;}constModal=(function(){letinstance=nullreturnfunction(){if(!instance){instance=createLayer()}returninstance}})()经过上面的修改,代码逻辑更加清晰,但目前不支持其他组件的泛化创建。这个时候我们就想一下,如何优化创建单例的方法,是否可以抽象出单例需要执行的功能。constcreateSingle=(function(fn){letinstance;returnfunction(){returninstance||(instance=fn.apply(this,arguments))}})()这样改造后,如果有创建iframe的方法,它也可以直接使用。constcreateIframe=function(){constiframe=document.createElement('iframe');iframe.style.display='无';document.body.appendChild(iframe);返回iframe}constsingleIframe=createSingle(createIframe)文档。querySelector("#open").onclick=function(){constiframe=singleIframe()iframe.style.display='block'}实际应用以上都是我们的小尝试,来看看社区的一些很棒的实现~比如:Redux,React中常用的状态管理工具,使用的是单例模式,它有一些要求。单一数据源:整个应用的状态只存在于一个存储中。状态是只读的:不要直接改变状态的值,改变状态的唯一方法是触发一个动作。Reducers是纯函数:您需要编写一个纯函数reducer来修改状态的值。我们来看一下Redux的源码。为了方便阅读一些被删除的逻辑判断和注释,可以看到闭包中的currentState每次都是通过store的getState方法获取的。单例模式在内存中只有一个实例,可以减少内存消耗,同时也可以在系统中设置一个全局访问点来优化和共享资源。以上就是单例模式的介绍。更多关于前端和设计模式的内容可以参考我的其他博文,持续更新中~