如果您看完了new的执行原理 相信您能够更好地理解此文。
引言
在编写复杂的 JavaScript 应用时,有时候我们需要确保某个类只有一个实例,并且提供一个访问它的全局访问点。这种设计模式被称为单例模式(Singleton Pattern)。其实单例模式在我们生活中很常见,初次进入某个网站寻求我们需要的资源(如影音、音乐)或是进行点赞等操作时,往往需要登录,如果我们一直关闭点击,它就会一直弹出。但是它其实一直都在那里的,并不是每次都要加载,那样很费时。
思考
考虑以下代码片段:
var Singleton = function (name) {
this.name = name;
}
var obj1 = new Singleton('kkk');
var obj2 = new Singleton('kkk');
console.log(obj1 === obj2);
我们知道,在new创建实例的时候首先会创建一个中间对象再引用给实例,因此每一次new,都会创造不同的引用地址,因此obj1 和 obj2 是两个不同的实例,所以 obj1 === obj2 的结果是 false。这引发了一个问题:是否可以让 obj1 和 obj2 相等,即在整个应用中只存在一个 Singleton实例?
由于js是一种动态类型的语言,变量的类型是在运行时确定的,而不是在编译时确定的。这意味着你可以在程序运行的过程中随时改变变量的类型。
因此呢,我们可以引入第三者var obj3=obj2,此时,obj3和obj2的引用地址都是一样的。
实现
基本实现思路
要实现单例模式,我们需要确保:
- 只有一个实例被创建。
- 提供一个全局访问点来访问这个实例。
静态方法实现单例模式
让我们通过代码来实现这一点:
var Singleton = function (name) {
this.name = name;
};
Singleton.prototype.getName = function () {
console.log(this.name);
};
// 静态方法,用于获取唯一的实例
Singleton.getInstance = function (name) {
if (!this.instance) {
this.instance = new Singleton(name);
}
return this.instance;
};
let obj1 = Singleton.getInstance('hfh');
let obj2 = Singleton.getInstance('qoi');
console.log(obj1 == obj2); // true
在这段代码中,我们定义了一个静态方法 getInstance。该方法首先检查 Singleton 类是否已经有一个实例。如果没有,它将创建一个新的 Singleton 实例并存储在 this.instance 中。无论何时调用 getInstance,它都会返回同一个实例。通过这种方式,我们确保了 Singleton 类只有一个实例。
单例模式的优点和适用场景
优点
- 控制实例数量:单例模式确保一个类只有一个实例。这对于需要集中管理的资源非常有用,例如数据库连接、日志记录器、缓存等。
- 全局访问:提供一个全局访问点,可以轻松访问实例而不必传递多个对象引用。这简化了代码结构,尤其是在大型应用中。
- 节省资源:通过确保只有一个实例,单例模式避免了重复创建对象,从而节省了内存和其他资源。
适用场景
- 配置管理:在应用程序中,有些配置参数是全局的,通过单例模式可以确保所有部分都使用相同的配置实例。
- 日志记录:日志记录器通常需要在整个应用中使用,单例模式可以确保日志记录器的统一和集中管理。
- 缓存:缓存机制需要在整个应用程序中访问和修改,单例模式可以确保缓存实例的唯一性和一致性。
- 线程池:在多线程环境中,线程池可以通过单例模式确保全局唯一,防止创建过多的线程池实例。
- 数据库连接:数据库连接管理需要集中控制,通过单例模式可以确保数据库连接的唯一性,防止连接过多导致资源浪费。
总结
单例模式是设计模式中最简单且最常用的一种,它确保一个类只有一个实例,并提供一个全局访问点。 实现单例模式的关键在于控制实例的创建,通过静态方法来管理实例的唯一性。有效地控制全局状态,节省资源,并简化代码结构,使得应用程序更易于维护和扩展。