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


当前回答

我发现下面是最简单的单例模式,因为使用new操作符可以立即在函数中使用它,消除了返回对象字面量的需要:

Var singleton = new(函数(){ var private = "一个私有值"; 这一点。printSomething = function() { console.log(私人); } }) (); singleton.printSomething ();

其他回答

最明确的答案应该是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; } }; })();

这个知识是基于我正在学习Java,虽然Java和Javascript是不同的,但单例的概念和Java如何做到这一点是一样的。在我看来,JS的类样式本身是干净的,而不是var初始化。

class Singleton {
    // use hashtag which entails that the variable can only be accessed from self scope
    static #instance = null;
    static getInstance() {
        if (this.#instance === null) this.#instance = new Singleton();
        return this.#instance;
    }

    // some class property
    hello = 'world';

    // or initialize the variable in the constructor, depend on your preference
    constructor() {
        // this.hello = 'world';
    }

    /* you can also add parameters on the constructor & getInstance
     * e.g. 
     * static getInstance(param1, param2) {...new Singleton(param1, param2)}
     * constructor(param1, param2) {...}
     */

}




// this is the same code for java and normal way for singleton for class
// just use static so you can get instance


// testing the singleton
var s1,s2;
s1 = Singleton.getInstance();
s2 = Singleton.getInstance();

// you cannot access the property, immediately
if (Singleton.hello === undefined) console.log('getInstance so you can access this');

console.log(s1.hello);
// result: "world"

console.log(s2.hello);
// result: "world"


// set the value of Singleton object
s2.hello = "hi";
    console.log(s1.hello);
    // result: "hi"

    console.log(s2.hello);
    // result: "hi"
// this is just an evidence which means that they are the same even in property level

if (s1 === s2) console.log("S1 & S2 is the same object");
// result: "S1 & S2 is the same object"

// don't use something like `var s1 = new Singleton();`
// this will defeat your purpose of just (1 object), one instance of class
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

我的意见:我有一个构造函数(CF),例如,

var A = function(arg1){
  this.arg1 = arg1
};

我只需要这个CF创建的每个对象都是相同的。

var X = function(){
  var instance = {};
  return function(){ return instance; }
}();

Test

var x1 = new X();
var x2 = new X();
console.log(x1 === x2)

你可以这样做:

var singleton = new (function() {
  var bar = 123

  this.foo = function() {
    // Whatever
  }
})()