在 JavaScript 中实现单例的最简单/最干净的方法

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


答案 1

我认为最简单的方法是声明一个简单的对象文字:

var myInstance = {
  method1: function () {
    // ...
  },
  method2: function () {
    // ...
  }
};

如果您希望在单例实例上使用私有成员,可以执行如下操作:

var myInstance = (function() {
  var privateVar = '';

  function privateMethod () {
    // ...
  }

  return { // public interface
    publicMethod1: function () {
      // All private members are accessible here
    },
    publicMethod2: function () {
    }
  };
})();

这被称为模块模式,它基本上允许您通过使用闭包来封装对象上的私有成员。

如果要阻止对单例对象的修改,可以使用 ES5 Object.freeze 方法将其冻结

这将使对象不可变,从而防止对其结构和值进行任何修改。

如果您使用的是 ES6,则可以非常轻松地使用 ES 模块表示单例,甚至可以通过在模块范围声明变量来保持私有状态

// my-singleton.js
const somePrivateState = []

function privateFn () {
  // ...
}

export default {
  method1() {
    // ...
  },
  method2() {
    // ...
  }
}

然后,您只需导入单例对象即可使用它:

import myInstance from './my-singleton.js'
// ...

答案 2

我认为最干净的方法是这样的:

var SingletonFactory = (function(){
    function SingletonClass() {
        //do stuff
    }
    var instance;
    return {
        getInstance: function(){
            if (instance == null) {
                instance = new SingletonClass();
                // Hide the constructor so the returned object can't be new'd...
                instance.constructor = null;
            }
            return instance;
        }
   };
})();

之后,您可以调用该函数

var test = SingletonFactory.getInstance();