最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to make a JavaScript singleton with a constructor without using return? - Stack Overflow

programmeradmin3浏览0评论

I currently know two ways to construct singletons in JavaScript. First:

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

It is perfect except that it does not have a constructor where I could run initialization code.

Second:

(function() {

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

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

})();

The first version does not have private properties nor does it have a constructor, but it is faster and simpler. The second version is more complex, ugly, but has a constructor and private properties.

I'm not in a need for private properties, I just want to have a constructor. Is there something I am missing or are the two approaches above the only ones I've got?

I currently know two ways to construct singletons in JavaScript. First:

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

It is perfect except that it does not have a constructor where I could run initialization code.

Second:

(function() {

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

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

})();

The first version does not have private properties nor does it have a constructor, but it is faster and simpler. The second version is more complex, ugly, but has a constructor and private properties.

I'm not in a need for private properties, I just want to have a constructor. Is there something I am missing or are the two approaches above the only ones I've got?

Share Improve this question asked Oct 10, 2010 at 11:49 TowerTower 103k131 gold badges364 silver badges518 bronze badges 1
  • 1 The second approach is not "ugly"; it's a natural part of the language. Being able to create functions with functions is one of Javascript's most powerful features. – Pointy Commented Oct 10, 2010 at 12:00
Add a comment  | 

6 Answers 6

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

Here is my solution with closures:

function Singleton() {

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

Test:

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

If you are just looking for a place to initialise your singleton, how about this?

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

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

Simple and elegant.

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

  this.publicproperty ="blabla";
}

This is basically the same as creating a function, then instantly assiging a new instace of it to the variable singleton. Like var singleton = new SingletonObject();

I highly advice against using singletons this way in javscript though because of the execution order is based on where in the file you place the object and not on your own logic.

What about this?

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'

I make it an actual Singleton with static functions and no this like so:

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;
发布评论

评论列表(0)

  1. 暂无评论