💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
## 闭包 对于 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 属性,那么单例模式也就被破坏了。