## 閉包
對于 JS 來說,巨大的靈活性使得其可以有多種方式實現單例模式,使用閉包方式來模擬私有數據,按照其思路可得:
```js
let single = (function () {
let unique
function getInstance () {
if(unique === undefined){
unique = new Construct()
}
return unique
}
function Construct () {
// ... 生成單例的構造函數的代碼
this.name = 'QZY'
this.age = 22
}
return {
getInstance : getInstance
}
})()
let t1 = single.getInstance()
let t2 = single.getInstance()
```
也有, t1 === t2 。
以上,unique 便是返回對象的引用,而 getInstance 便是靜態方法獲得實例。Construct 便是創建實例的構造函數。
可以通過 `single.getInstance()` 來獲取到單例,并且每次調用均獲取到同一個單例。這就是 單例模式 所實現的效果。
不過,對于JS來說,顯然以上循規蹈矩的方式顯得過于笨重,在不同的場景以不同的方式實現單體模式正是 JS 的優勢。
## 對象字面量就是一個單例
```js
let singleton = {
attr: 'singleton',
method: function () {
return this.attr
}
}
let t1 = singleton
let t2 = singleton
```
那么很顯然的, t1 === t2 。
十分簡單,并且非常使用,不足之處在于沒有什么封裝性,所有的屬性方法都是暴露的。對于一些需要使用私有變量的情況就顯得心有余而力不足了。當然在對于 this 的問題上也是有一定弊端的。
## 構造函數內部判斷
```js
function Singleton (){
// 確保只有單例
if( Singleton.unique !== undefined ){
return Singleton.unique
}
// 其他代碼
this.name = "QZY"
this.age = 22
Singleton.unique = this
}
let t1 = new Singleton ()
let t2 = new Singleton ()
```
那么也有的, t1 === t2 。
也是非常簡單,無非就是提出一個屬性來做判斷,但是該方式也沒有安全性,一旦我在外部修改了 Construct 的 unique 屬性,那么單例模式也就被破壞了。