用JavaScript实现单例模式的最简单/最干净的方法是什么?


当前回答

对我来说,最简单/最干净的也意味着简单地理解,没有花哨的东西,就像Java版本的讨论中讨论的那样:

在Java中实现单例模式的有效方法是什么?

从我的角度来看,最简单/最干净的答案是:

Jonathan的回答是:在Java中实现单例模式的有效方法是什么?

它只能部分地翻译成JavaScript。JavaScript中的一些区别是:

构造函数不能是私有的 类不能有声明的字段

但考虑到最新的ECMA语法,有可能接近:

作为JavaScript类示例的单例模式

 class Singleton {

  constructor(field1,field2) {
    this.field1=field1;
    this.field2=field2;
    Singleton.instance=this;
  }

  static getInstance() {
    if (!Singleton.instance) {
      Singleton.instance=new Singleton('DefaultField1','DefaultField2');
    }
    return Singleton.instance;
  }
}

示例使用

console.log(Singleton.getInstance().field1);
console.log(Singleton.getInstance().field2);

例子的结果

DefaultField1
DefaultField2

其他回答

最明确的答案应该是Addy Osmani所著的《学习JavaScript设计模式》一书。

var mySingleton = (function () { // Instance stores a reference to the singleton var instance; function init() { // Singleton // Private methods and variables function privateMethod(){ console.log( "I am private" ); } var privateVariable = "I'm also private"; var privateRandomNumber = Math.random(); return { // Public methods and variables publicMethod: function () { console.log( "The public can see me!" ); }, publicProperty: "I am also public", getRandomNumber: function() { return privateRandomNumber; } }; }; return { // Get the singleton instance if one exists // or create one if it doesn't getInstance: function () { if ( !instance ) { instance = init(); } return instance; } }; })();

这应该可以工作:

function Klass() {
   var instance = this;
   Klass = function () { return instance; }
}

单例模式:

确保一个类只有一个实例,并提供对它的全局访问点。

单例模式将特定对象的实例数量限制为一个。这个单一实例称为单例。

定义返回唯一实例的getInstance()。 负责创建和管理实例对象。

单例对象被实现为一个即时匿名函数。函数立即执行,将它括在括号中,然后再加上两个括号。它被称为匿名,因为它没有名字。

示例程序

var Singleton = (function () { var instance; function createInstance() { var object = new Object("I am the instance"); return object; } return { getInstance: function () { if (!instance) { instance = createInstance(); } return instance; } }; })(); function run() { var instance1 = Singleton.getInstance(); var instance2 = Singleton.getInstance(); alert("Same instance? " + (instance1 === instance2)); } run()

使用ES6类和私有静态字段。调用Singleton类的新实例将返回相同的实例。实例变量也是私有的,不能在类外部访问。

class Singleton {
  // # is a new Javascript feature that denotes private
  static #instance;

  constructor() {
    if (!Singleton.#instance) {
      Singleton.#instance = this
    } 
    return Singleton.#instance
  }

  get() {
    return Singleton.#instance;
  }
}

const a = new Singleton();
const b = new Singleton();
console.log(a.get() === b.get()) // true
console.log(Singleton.instance === undefined) // true

我需要几个单人间:

延迟初始化 初始参数

这就是我想到的:

createSingleton ('a', 'add', [1, 2]);
console.log(a);

function createSingleton (name, construct, args) {
    window[name] = {};
    window[construct].apply(window[name], args);
    window[construct] = null;
}

function add (a, b) {
    this.a = a;
    this.b = b;
    this.sum = a + b;
}

args必须是Array,所以如果你有空变量,只需要传入[] 我在函数中使用了window对象,但我本可以传入一个参数来创建自己的作用域 name和构造参数只是字符串,以便window[]工作,但有一些简单的类型检查,window.name和window.name。构造也是可能的。