Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript singleton: How to access private variables?

I have this singleton. The public functions allow to set private variables but I am not able to set them in the way that I am able to use them in the private methods:

var ServiceInterface = (function () {
  // Instance stores a reference to the Singleton
  var instance;

  function init() {
    // Singleton
    // Private methods and variables
    var m_action;

    function performAction() {
      alert(m_action);
    }

    return {
      // Public methods and variables
      callBackend: function (sAction) {
        m_action = sAction;
      }
    };
  };
})

m_action is not available throughout the public and private section of the singleton. What am I doing wrong?

like image 779
AntonSack Avatar asked Dec 06 '25 11:12

AntonSack


2 Answers

I think you're referring to this

var ServiceInterface = (function () {
    var m_action;

    function performAction() {
      alert(m_action);
    }

    return {
      // Public methods and variables
      callBackend: function (sAction) {
        m_action = sAction;
        performAction();
      }
    };
})()

ServiceInterface.callBackend("Hello world");

You need to execute anonymous function. Running it enables to create variables and functions defined with the anonymous function and these cannot be seen outside. Most of js libraries use this convention to create modules and to avoid infecting the global scope

var ServiceInterface = (function () {
   // code inside 
})()

These are the variables and functions confined within the scope of anonymous function executed

// var ServiceInterface = (function () {
    var m_action;

    function performAction() {
      alert(m_action);
    }

// })()

Finally, return a javascript object that will expose functions that can be accessible outside the anonymous function scope

//var ServiceInterface = (function () {
//  var m_action;
//    
//  function performAction() {
//       alert(m_action);
//  }

    return {
      // Public methods and variables
      callBackend: function (sAction) {
        m_action = sAction;
        performAction();
      }
    };
//})()

However, why go through the trouble of making private variable and method for a singleton?

like image 134
OnesimusUnbound Avatar answered Dec 08 '25 23:12

OnesimusUnbound


This is how you create a singleton with a private member variable.

ServiceInterface = new (function() {
    var m_action = false;

    this.setAction = function(s) {
        m_action = s;
    };
    this.getAction = function() {
        return m_action;
    };

    this.performAction = function() {
        alert(ServiceInterface.getAction());
    };

    this.createCallback = function() {
        return function(sAction) {
            ServiceInterface.setAction(sAction);
        };
    }
})();
ServiceInterface.setAction("secret");
ServiceInterface.performAction();

ServiceInterface becomes a singleton because the constructor function is thrown away after it's created. ServiceInterface = new (.....)(); is how it's executed right after being declared. It's a singleton because there is no way for someone to create another instance.

I don't use var to create the instance. When you exclude var and you're not inside a function the new variable will be attached to the prototype of the parent object. In the browser this will be window. window is like a global singleton in javascript.

The local variable m_action is persisted because setAction and getAction reference it as closure functions, and the variable is attached to their scope. So they can be used as setter/getter methods.

You can now use ServiceInterface.setAction(sAction); in your callbacks to set the private member.

http://jsfiddle.net/thinkingmedia/w7DdE/6/

like image 42
Reactgular Avatar answered Dec 09 '25 01:12

Reactgular



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!