【发布时间】:2021-02-18 19:06:26
【问题描述】:
我已经通过以下方式实现了单例模式:
class Singleton {
static #instance_holder = [];
constructor() {
if (0 !== Singleton.#instance_holder.length) return Singleton.#instance_holder[0];
Singleton.#instance_holder.push(this);
Object.preventExtensions(this);
console.log("You'll see me only once, when the object is first instantiated.");
}
}
就常规声明/分配而言,这似乎工作正常:
const s1 = new Singleton();
//OUTPUT: You'll see me only once, when the object is first instantiated.
const s2 = new Singleton(); //no additional instantiation, the existing one is assigned to s2
s1 instanceof Singleton //true
s2 instanceof Singleton //true
s1 === s2 //true
但是,仍然可以使用 Object.create 或 Object.assign 或 JSON.parse(JSON.stringify(s1)) 克隆实例 (s1)。
const clone = Object.create(s1);
clone instanceof Singleton //true
clone === s1 //false
如何防止对象以这些方式被克隆?
【问题讨论】:
-
为什么克隆有问题?
-
因为这样会有 2 个 Singleton 实例,有效地将其变成 Doubleton!
-
你想阻止谁?让糟糕的开发人员弄乱他们自己的代码,而不是你的问题。
-
好吧,这真的不可能。即使在 Java 或 C# 中,您也可以使用反射来绕过单例。防止多个实例没有多大意义,因为最终它们是不便而不是问题。如果编写代码的人想要不便,甚至花费额外的精力来不便,那就让他们吧。
-
另外,单例的实现是一种矫枉过正的做法。只需使用一个模块并导出一个实例或一个工厂(如果你想要一个池可能)。那么就不用写代码来阻止
new工作了。
标签: javascript singleton clone