javascript singleton question

前端 未结 10 2040
闹比i
闹比i 2020-12-12 20:08

I just read a few threads on the discussion of singleton design in javascript. I\'m 100% new to the Design Pattern stuff but as I see since a Singleton by definition won\'t

相关标签:
10条回答
  • 2020-12-12 20:26

    The ES5 spec lets us use Object.create():

    var SingletonClass = (function() {
        var instance;
        function SingletonClass() {
            if (instance == null) {
                instance = Object.create(SingletonClass.prototype);
            }
    
            return instance;
        }
    
        return {
            getInstance: function() {
                return new SingletonClass();
            }
       };
    })();
    
    var x = SingletonClass.getInstance();
    var y = SingletonClass.getInstance();
    var z = new x.constructor();
    

    This is nice, since we don't have to worry about our constructor leaking, we still always end up with the same instance.

    This structure also has the advantage that our Singleton doesn't construct itself until it is required. Additionally, using the closure as we do here prevents external code from using our "instance" variable, accidentally or otherwise. We can build more private variables in the same place and we can define anything we care to export publically on our class prototype.

    0 讨论(0)
  • 2020-12-12 20:27

    I have used the second version (var singleton = {};) for everything from Firefox extensions to websites, and it works really well. One good idea is to not define things inside the curly brackets, but outside it using the name of the object, like so:

    var singleton = {};
    singleton.dothis = function(){
    
    };
    singleton.someVariable = 5;
    
    0 讨论(0)
  • 2020-12-12 20:28

    How about this:

    function Singleton() {
    
        // ---------------
        // Singleton part.
        // ---------------
    
        var _className = null;
        var _globalScope = null;
    
        if ( !(this instanceof arguments.callee) ) {
            throw new Error("Constructor called as a function.");
        }
    
        if ( !(_className = arguments.callee.name) ) {
            throw new Error("Unable to determine class name.")
        }
    
        _globalScope = (function(){return this;}).call(null);
    
        if ( !_globalScope.singletons ) {
            _globalScope.singletons = [];
        }
    
        if ( _globalScope.singletons[_className] ) {
            return _globalScope.singletons[_className];
        } else {
            _globalScope.singletons[_className] = this;
        }
    
        // ------------
        // Normal part.
        // ------------
    
        var _x = null;
    
        this.setx = function(val) {
            _x = val;
        }; // setx()
    
        this.getx = function() {
            return _x;
        }; // getx()
    
        function _init() {
            _x = 0; // Whatever initialisation here.
        } // _init()
        _init();
    
    } // Singleton()
    
        var p = new Singleton;
        var q = new Singleton;
    
        p.setx(15);
        q.getx(); // returns 15
    
    0 讨论(0)
  • 2020-12-12 20:31

    I stole this from CMS / CMS' answer, and changed it so it can be invoked as:

    MySingleton.getInstance().publicMethod1();
    

    With the slight alternation:

    var MySingleton = {                // These two lines
    
        getInstance: function() {      // These two lines
    
          var instance = (function() {
    
            var privateVar;
    
            function privateMethod () {
              // ...
              console.log( "b" );
            }
    
            return { // public interface
              publicMethod1: function () {
                  // private members can be accessed here
                  console.log( "a" );
               },
              publicMethod2: function () {
                // ...
                privateMethod();
              }
            };
          })();
    
          singleton = function () { // re-define the function for subsequent calls
            return instance;
          };
    
          return singleton(); // call the new function
        }
    }
    
    0 讨论(0)
提交回复
热议问题