如何知道 class 的实例是否来自单例?

How to know if an instance of class came from a Singleton?

我必须评估 class 的实例是否来自 Singleton 或否?

我知道在 JavaScript 中创建一个 Singleton 我需要在构造函数中保存一个变量 instance (名称可以是任何名称)保存 this.

class Singleton {
  constructor() {
    const instance = this.constructor.instance;
    if (instance) return instance;
    this.constructor.instance = this;
  }
}

但是如果我没有那个代码,我只是取回 class 的实例,例如:

let singletonOrMaybeNo = new Singleton()

而我只有singletonOrMaybeNo

我如何知道该实例是单例还是否?

谢谢!!

instanceof 将 return true 如果对象是 的 实例 class:

class Singleton {
  constructor() {
    const instance = this.constructor.instance;
    if (instance) return instance;
    this.constructor.instance = this;
  }
}

let singletonOrMaybeNo = new Singleton();

console.log(singletonOrMaybeNo instanceof Singleton);

您可以检查具有相同构造函数的实例的相同身份。

class Singleton {
  constructor() {
    const instance = this.constructor.instance;
    if (instance) return instance;
    this.constructor.instance = this;
  }
}

class NoSingleton {
  constructor() {
  }
}


let singletonOrMaybeNo = new Singleton,
    other = new NoSingleton;

// works only with known constructor
console.log(singletonOrMaybeNo === new Singleton);

// takes the constructor from the instance (kudos to Jonas Wilms)
console.log(singletonOrMaybeNo === new singletonOrMaybeNo.constructor);

console.log(other === new other.constructor);

"singleton class" 的概念来自只有 classes 的语言(例如 Java),但是 JavaScript 比 classes (objects, functions, "global code"),因此我们不需要用假的 class 来模仿单一对象的创建,我们可以这样做:

   const singleton = { some: 0, properties: 0 };
   // initialization goes here

你说得对,可以创建一个 "singleton class",但这没有任何好处,它只是增加了样板代码,而且在我看来,这会使代码更难理解(正如我所料new Class 创建实例,而不是 return 单例)。

要检查实例是否来自 class 中写入的 "singleton pattern way",您可以简单地检查实例:

   instance === instance.constructor.instance

但我不确定这是否有用。你是否真的需要那些 class 是值得怀疑的,如果你真的需要那些,那么你可能只有其中的几个,并且检查实例是否是 instanceof 会更不容易出错其中之一:

  instance instanceof Singleton1 || instance instanceof Singleton2

如果你的 "singleton class"es 不是你写的,你只知道它们来自一个可能 return 现有实例的构造函数,那么唯一的方法就是创建一个新的class 的实例,并检查同一实例是否被 returned:

  instance === new instance.constructor

但是,如果构造函数需要参数,那么它将中断,或者如果它只是一个常规的 class 实例,您将创建一个不必要的实例,这可能会导致不必要的副作用。

毕竟:你为什么需要那个?