保证一个类仅有一个实例,并提供一个全局访问点javascript
想象一下某些web应用,当点击登陆按钮时,会弹出一个登陆框,不管你点击多少次这个登陆按钮,登陆框都只会出现一个,不会出现多个登陆框。同时不会频繁的进行删除和添加,而是同一个登陆框进行隐藏和显示,由于删除和添加十分耗费性能,因此单例能够达到最大化的效能利用。登陆框这个例子就是单例模式最典型的应用,符合业务的需求,又可以提升性能html
一个简单的单例模式,无非就是用一个变量指示要建立的实例是否已经建立过了,若是已经建立过了,则在下一次使用实例时,直接返回复用,若是没有建立过,则建立并保存到变量中。
java
可是这时候的这个单例类是“不透明”的,由于咱们一般习惯使用new XXX()
的方式来实例化一个类,而不是经过使用者不知道的XXX.getInstance()
的方式来获取单例对象。
因此咱们应该使用透明的单例类web
先介绍下IIFEapp
IIFE( 当即调用函数表达式)是一个在定义时就会当即执行的 JavaScript 函数 --- MDN函数
eg.
之因此使用IIFE,就是限制JS的变量做用域,在ES5中,没有块级做用域,只有函数做用域一种,因此提供一种模拟块级做用域的方法就是IIFE。咱们的透明单例模式就是使用IIFE来模拟。
性能
使用IIFE来避免变量污染,把在IIFE中建立的类return出去,供外部经过new XXX()
的形式调用。缺点是增长了程序的复杂度,不利于阅读。
在构造函数CreateDiv中:this
实际上作了两件事,prototype
这样就不符合单一职责原则,这个构造函数就变得不纯粹了。若是哪天我不想使用单例了,我要在页面建立普通的实例,建立多个不同的div,还须要去修改CreateDiv构造函数,去掉控制单一实例的那一段,但页面中使用此单例的代码可能就用不了,故会带来没必要要的麻烦。因此咱们应该使用单例代理。代理
上面的问题咱们能够用单例代理来解决,经过引入一个代理类,代理普通CreateDiv类,使之变为单例类。
咱们把负责单例类管理的逻辑放到了单独的ProxyCreateDiv类中,CreateDiv类仍是一个普通的建立实例的类,这样保证了单一职责原则,组合起来就能达到单一职责原则。
以上就是单例类的建立模式,还有一类单例模式的应用,就是文章开头说的登陆框,点击登陆按钮,登陆框会弹出,而不管点击多少次,登陆框都只会弹出一个,这个登陆框就是单例的,稍后我会新写一篇文章分享这种单例模式的应用,敬请关注。