如何防止单例对象被克隆?
How to prevent a Singleton object from being cloned?
我通过以下方式实现了单例模式:
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.");
}
}
就常规 declaration/assignment 而言,这似乎工作正常:
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
如何防止对象以这些方式被克隆?
基本上,你不能。没有可以防止克隆的 JS 机制。
如果某个东西是单例非常重要,那么它可能是 class 中您真正关心的东西。在那种情况下,最好将它放在全局范围内并让 class 引用它。
const data = {};
class Singleton {
// singleton setup
doSomething() {
return data.something();
}
}
这将确保即使单例被克隆,只要它使用相同的数据源,它仍然像单例一样。
也就是说...我真的不建议这样做。我真的想不出在什么情况下您实际上需要强制执行真正的单身人士。如果有人对他们的代码做了一些愚蠢的事情,那是他们的问题。
我通过以下方式实现了单例模式:
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.");
}
}
就常规 declaration/assignment 而言,这似乎工作正常:
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
如何防止对象以这些方式被克隆?
基本上,你不能。没有可以防止克隆的 JS 机制。
如果某个东西是单例非常重要,那么它可能是 class 中您真正关心的东西。在那种情况下,最好将它放在全局范围内并让 class 引用它。
const data = {};
class Singleton {
// singleton setup
doSomething() {
return data.something();
}
}
这将确保即使单例被克隆,只要它使用相同的数据源,它仍然像单例一样。
也就是说...我真的不建议这样做。我真的想不出在什么情况下您实际上需要强制执行真正的单身人士。如果有人对他们的代码做了一些愚蠢的事情,那是他们的问题。