在 JavaScript ES6+ 中实现单例模式:分步指南

1. 什么是单例模式?

单例模式是一种软件设计模式,它可以确保一个类只有一个实例,并提供全局访问点来访问该实例。

在JavaScript中,可以使用单例模式来确保只能创建一个特定对象的实例。这在许多情况下是有用的,例如:

全局配置对象

日志记录器

唯一的用户引导程序(例如,只能存在一个登录框)

2. 实现单例模式的方法

2.1 使用闭包

一个简单的实现单例模式的方法是使用闭包。

const mySingleton = (function() {

let instance;

function init() {

// 私有方法和变量

function privateMethod() {

console.log('I am private');

}

let privateVariable = 'I am also private';

// 公有方法和变量

return {

publicMethod: function() {

console.log('The public can see me!');

},

publicProperty: 'I am also public',

getPrivateVariable: function() {

return privateVariable;

},

setPrivateVariable: function(value) {

privateVariable = value;

}

};

}

return {

getInstance: function() {

if (!instance) {

instance = init();

}

return instance;

}

};

})();

const singletonA = mySingleton.getInstance();

const singletonB = mySingleton.getInstance();

console.log(singletonA === singletonB); // true

这个实现中,我们使用了一个 IIFE(立即调用函数表达式)来创建一个私有作用域来存储实例。init函数只在第一次创建实例时调用一次,并返回一个对象字面量,公开了一些公共方法和变量。getInstance函数确保只有一个实例被创建,并提供对该实例的全局访问点。

2.2 ES6类的静态方法

在ES6中,我们可以使用类构造函数和静态方法来实现单例模式。

class mySingleton {

static instance;

constructor() {

if (mySingleton.instance) {

return mySingleton.instance;

}

// 私有方法和变量

function privateMethod() {

console.log('I am private');

}

let privateVariable = 'I am also private';

// 公有方法和变量

this.publicMethod = function() {

console.log('The public can see me!');

};

this.publicProperty = 'I am also public';

this.getPrivateVariable = function() {

return privateVariable;

};

this.setPrivateVariable = function(value) {

privateVariable = value;

};

mySingleton.instance = this;

}

static getInstance() {

if (!mySingleton.instance) {

mySingleton.instance = new mySingleton();

}

return mySingleton.instance;

}

}

const singletonA = new mySingleton();

const singletonB = new mySingleton();

console.log(singletonA === singletonB); // true

const singletonC = mySingleton.getInstance();

const singletonD = mySingleton.getInstance();

console.log(singletonC === singletonD); // true

在这里,我们使用了ES6类的静态方法来存储和访问实例。构造函数中,我们先检查是否已经有一个实例存在,并如果有,直接返回该实例。如果不存在,就创建一个新的实例。getInstance静态方法确保只有一个实例被创建,并提供对该实例的全局访问点。

3. 总结

单例模式是一种非常有用的设计模式,它可确保一个类只有一个实例,并提供全局访问点来访问该实例。在JavaScript中,我们可以使用闭包或ES6类的静态方法来实现单例模式。

需要注意的是,单例模式可以使代码更易于扩展,也可以使代码更困难,取决于实现的方式。因此,在考虑使用单例模式时,请牢记其优缺点,以确保使用正确的方式。