单例是一种面向对象的软件设计模式,它确保给定类只实例化一次。在许多不同的情况下,它可以很有用,例如创建应用程序中共享的全局对象。虽然JavaScript支持面向对象的编程,但它没有提供简单的方法来实现这种模式。
最灵活的方法,就是使用代理对象(Proxy object)。下面是一个基本用法示例:
const singletonify = (className) => {
return new Proxy(className.prototype.constructor, {
instance: null,
construct: (target, argumentsList) => {
if (!this.instance)
this.instance = new target(...argumentsList);
return this.instance;
}
});
}
这里还有个简单的应用示例,可以更好地理解它:
class MyClass {
constructor(msg) {
this.msg = msg;
}
printMsg() {
console.log(this.msg);
}
}
MySingletonClass = singletonify(MyClass);
const myObj = new MySingletonClass('first');
myObj.printMsg(); // 'first'
const myObj2 = new MySingletonClass('second');
myObj2.printMsg(); // 'first'
在上面的示例中,你可以看到第二次实例化MySingletonClass时,并没有创建新的实例。这是因为已经存在一个实例,所以它被返回,而不是创建一个新的对象。如前所述,这是一个单例函数的简化实现。它可以扩展以进一步修改行为,或者在后续调用中使用传递给构造函数的数据来更新它持有的实例。