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


当前回答

在ES6中正确的方法是:

MyClass { 构造函数(){ if (MyClass._instance) { 抛出新的错误("单例类不能实例化超过一次。") } MyClass。_instance = this; / /……其余的构造函数代码在此之后 } } var instanceOne = new MyClass() //执行成功 var instanceTwo = new MyClass() //抛出错误

或者,如果你不想在创建第二个实例时抛出错误,你可以只返回最后一个实例,如下所示:

MyClass { 构造函数(){ if (MyClass._instance) { 返回MyClass._instance } MyClass。_instance = this; / /……其余的构造函数代码在此之后 } } var instanceOne = new MyClass() var instanceTwo = new MyClass() console.log(instanceOne === instanceTwo) //日志为true

其他回答

在Node.js版本6中工作:

class Foo {
  constructor(msg) {

    if (Foo.singleton) {
      return Foo.singleton;
    }

    this.msg = msg;
    Foo.singleton = this;
    return Foo.singleton;
  }
}

我们测试:

const f = new Foo('blah');
const d = new Foo('nope');
console.log(f); // => Foo { msg: 'blah' }
console.log(d); // => Foo { msg: 'blah' }

模块模式:“更具可读性的风格”。您可以很容易地看到哪些方法是公共的,哪些是私有的

var module = (function(_name){
   /* Local Methods & Values */
   var _local = {
      name : _name,
      flags : {
        init : false
      }
   }

   function init(){
     _local.flags.init = true;
   }

   function imaprivatemethod(){
     alert("Hi, I'm a private method");
   }

   /* Public Methods & variables */

   var $r = {}; // This object will hold all public methods.

   $r.methdo1 = function(){
       console.log("method1 calls it");
   }

   $r.method2 = function(){
      imaprivatemethod(); // Calling private method
   }

   $r.init = function(){
      inti(); // Making 'init' public in case you want to init manually and not automatically
   }

   init(); // Automatically calling the init method

   return $r; // Returning all public methods

})("module");

现在你可以使用公共方法,比如

module.method2 ();// ->我正在调用一个私有方法超过一个公共方法警报(“嗨,我是一个私有方法”)

http://jsfiddle.net/ncubica/xMwS9/

这也是一个单例:

function Singleton() {
    var i = 0;
    var self = this;

    this.doStuff = function () {
        i = i + 1;
        console.log('do stuff', i);
    };

    Singleton = function () { return self };
    return this;
}

s = Singleton();
s.doStuff();

简单的例子

class Settings {

  constructor() {
    if (Settings.instance instanceof Settings) {
      return Settings.instance;
    }
    this.settings = {
      id: Math.floor(Math.random() * 4000),
      name: "background",
    };
    Object.freeze(this.settings);
    Object.freeze(this);
    Settings.instance = this;
  }

}

var o1 = new Settings();
var o2 = new Settings();

console.dir(o1);
console.dir(o2);

if (o1 === o2) {
  console.log("Matched");
}
function Once() {
    return this.constructor.instance || (this.constructor.instance = this);
}

function Application(name) {
    let app = Once.call(this);

    app.name = name;

    return app;
}

如果你在上课:

class Once {
    constructor() {
        return this.constructor.instance || (this.constructor.instance = this);
    }
}

class Application extends Once {
    constructor(name) {
        super();

        this.name = name;
    }
}

测试:

console.log(new Once() === new Once());

let app1 = new Application('Foobar');
let app2 = new Application('Barfoo');

console.log(app1 === app2);
console.log(app1.name); // Barfoo