單例模式
單例就是確保一個類只有一個例項,任何時候呼叫的例項都是同一個,這個例項只會初始化一次。
方式一
實現步驟:
- 最簡單的——物件字面量的方式
其字面量裡可以包含大量的屬性和方法,直接建立好的單例物件。這樣建立的物件變數全域性化了,
var instance={
prop1: "prop1",
prop2: "prop2",
method1: function () {
console.log('hello world');
}
}
複製程式碼
- 擴充套件該單例物件可以新增自己的私有變數和方法,只暴露公有變數和方法方式,通過閉包的方式來實現。
var mySingleton = function(){
// 私有變數和方法
var priv_prop='private prop';
var priv_mtd = function(){
console.log(priv_prop)
}
// 公有變數和方法,能訪問私有變數和方法
return {
pub_mtd: function(){
priv_mtd()
},
pub_prop: 'public prop'
}
}
var instance = mySingleton();
instance.pub_mtd(); // 輸出 'private prop'
console.log(instance.pub_prop); // 輸出 'public prop'
複製程式碼
事實上這裡的mySingleton()並不是單例的,只是在第一步上做了擴充套件可以訪問私有變數
var instance2 = mySingleton();
instance === instance2 //false
複製程式碼
- 真正的建立例項,每次呼叫的都是同一個物件例項,第一呼叫才會初始化。
var Singleton = (function(){
// 這裡定義單例程式碼
var instance;
function init(){
return {
pub_mtd: function(){
console.log('this is pub_mtd');
},
pub_prop:'this is pub_prop'
}
};
return {
getInstance:function(){
if (!instance){
instance = init()
}
return instance
}
}
})()
/*呼叫公有的方法的時候初始化例項:*/
Singleton.getInstance().pub_mtd();
let a=Singleton.getInstance();
let b=Singleton.getInstance();
a === b // true 此時才算是真正的單例
a.pub_mtd === b.pub_mtd //true
a.pub_mtd() //列印出'this is pub_mtd';
複製程式碼
此時才算是真正的單例,任何時候呼叫Singleton.getInstance()都是同一個例項。
其他實現方式
方法1-通過重寫建構函式直接呼叫前一次生成的例項
function Instance(){
var instance = this;
console.log(111)
this.prop='prop';
this.mtd=function(){
console.log(this.prop);
}
//重寫建構函式
Instance = function(){
console.log(222)
return instance;
}
}
var a = new Instance() // 列印出111,同時建構函式被重寫,
var b = new Instance() // 列印出222,直接返回前一次呼叫快取的instance
a === b // true
複製程式碼
方法2-把首次生成的例項快取到建構函式的屬性上
function Instance(){
if (typeof Instance.instance === 'object'){
return Instance.instance
}
this.prop='prop';
this.mtd=function(){
console.log(this.prop);
};
// 快取
Instance.instance=this;
// 隱式返回 this
}
var ins1=new Instance();
var ins2=new Instance();
ins1 === ins2
複製程式碼
方法3-內部重寫建構函式,修改原型屬性,重設建構函式指標
function Instance(){
var instance;
console.log(1)
// 二次呼叫的建構函式
Instance = function Instance(){
console.log(2)
return instance;
};
console.log(3)
// 後期處理原型屬性
Instance.prototype = this;
// 例項
instance = new Instance();
console.log(4)
// 重設建構函式指標
instance.constructor = Instance;
instance.prop='prop';
instance.mtd=function(){
console.log(instance.prop)
}
console.log(5)
return instance
}
var a = new Instance();
// 13245
var b = new Instance();
// 2
複製程式碼