1、单例模式
保证一个类仅有一个实例,并提供一个访问它的全局访问点
1.1 传统的单例模式
var Singleton=function(name){ this.name=name; } Singleton.prototype.getName=function(){ alert(this.name); } Singleton.getInstance=(function(){ var instance=null; return function (name) { if(!instance){ instance=new Singleton(name); } return instance; } })(); var a=Singleton.getInstance('sven1'); var b=Singleton.getInstance('sven2'); alert(a===b);//true
1.2 JavaScript中的单例模式
单例模式的核心是确保只有一个实例,并提供全局访问
JavaScript中,可以把全局变量当成单例来使用
var a={};
以这种方式创建对象a,这个对象a是独一无二的,并且在全局作用域可以被访问
全局变量容易造成命名空间污染,使用命名空间可以减少全局变量的数量
var namespace1={ a:function(){ alert(1); }, b:function(){ alert(2); } };
1.3 应用举例--惰性单例
以点击“登陆”按钮弹出登陆框为例
<html> <body> <button id="loginBtn" >登陆</button> </body> <script> var createLoginLayer=(function(){ var div; return function(){ if(!div){ div=document.createElement('div'); div.innerHTML='我是登陆浮窗'; div.style.display='none'; document.body.appendChild(div); } return div; } })(); document.getElementById('loginBtn').onclick=function(){ var loginLayer=createLoginLayer(); loginLayer.style.display='block'; }; </script> </html>
上述示例违反了单一职责原则,创建对象和管理单例逻辑耦合在一起了
var getSingle= function (fn) { var result; return function () { return result || (result = fn.apply(this,arguments)); } }; var createLoginLayer=function(){ var div=document.createElement('div'); div.innerHTML='我是登陆符窗'; div.style.display='none'; document.body.appendChild(div); return div; }; var createSingleLoginLayer=getSingle(createLoginLayer()); document.getElementById('loginBtn').onclick=function(){ var loginLayer=createSingleLoginLayer(); loginLayer.style.display='block'; }; //当需要创建唯一的iframe用于动态加载第三方页面时 var createSingleIframe=getSingle(function () { var iframe=document.createElement('iframe'); document.body.appendChild(iframe); }); document.getElementById('loginBtn').onclick=function(){ var loginLayer=createSingleIframe(); loginLayer.src='http://www.google.com'; };