## 闭包
对于 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 属性,那么单例模式也就被破坏了。