如何使用构造函数制作JavaScript单例而不使用return?

时间:2010-10-10 11:49:11

标签: javascript

我目前知道在JavaScript中构建单例的两种方法。第一:

var singleton = {
 publicVariable: "I'm public",
 publicMethod: function() {}
};

它是完美的,除了它没有我可以运行初始化代码的构造函数。

第二

(function() {

var privateVariable = "I'm private";
var privateFunction = function() {}

return {
 publicVariable: "I'm public",
 publicMethod: function () {}
}

})();

第一个版本没有私有属性,也没有构造函数,但它更快更简单。第二个版本更复杂,更丑陋,但有一个构造函数和私有属性。

我不需要私有属性,我只想拥有一个构造函数。是否有我遗漏的东西或者是我唯一拥有的两种方法?

6 个答案:

答案 0 :(得分:7)

function Singleton() {
  if ( Singleton.instance )
    return Singleton.instance;
  Singleton.instance = this;
  this.prop1 = 5;
  this.method = function() {};
}​

答案 1 :(得分:2)

这是我的闭包解决方案:

function Singleton() {

    Singleton.getInstance = (function(_this) {
        return function() { return _this; };
    })(this);
}

测试:

var foo = new Singleton();
var bar = Singleton.getInstance();
foo === bar; // true

答案 2 :(得分:2)

如果你只是想找一个初始化单身的地方,那怎么样?

var singleton = {
    'pubvar': null,
    'init': function() {
        this.pubvar = 'I am public!';
        return this;
    }
}.init();

console.assert(singleton.pubvar === 'I am public!');

简单而优雅。

答案 3 :(得分:1)

var singleton = new function() {  // <<----Notice the new here
  //constructorcode....

  this.publicproperty ="blabla";
}

这与创建函数基本相同,然后立即将其新的实例分配给变量singleton。像var singleton = new SingletonObject();

我强烈建议不要在javscript中以这种方式使用单例,因为执行顺序是基于文件放置对象而不是你自己的逻辑。

答案 4 :(得分:1)

这个怎么样?

var Singleton = (function() {
    var instance;

    // this is actual constructor with params
    return function(cfg) {
        if (typeof instance == 'undefined') {
            instance = this;
            this.cfg = cfg;
        }
        return instance;
    };
})();

var a = new Singleton('a');
var b = new Singleton('b');

//a === b; <-- true
//a.cfg <-- 'a'
//b.cfg <-- 'a'

答案 5 :(得分:0)

我使它成为具有静态功能且没有this的实际Singleton,例如:

class S {
    //"constructor"
    static init() {
        //Note: Since it's a singleton, there's no "this" instance.
        //Instead, you store variables directly on the class.
        S.myVar = 7;
    }

    static myOtherFunc() {
        alert(S.myVar);
    }
}
//Immediately call init() to make it the "constructor".
//Alternatively, you can call init() elsewhere if you'd
//like to initialize it at a particular time.
S.init();

//Later:
S.myOtherFunc();
S.myVar = 10;