Better way to access private members in Javascript

javascript, prototype

Solution

The use of function scope variables and closures to simulate private variables/functions is a well established idiom in the javascript community. If the variable is truly intended to be private, I see no drawback to this approach (although some claim that performant code on certain browsers/hosts has to pay attention to how many closures get created).

In your example, the private_method (and its environment) is shared across all objects - since your public_method closure is created only the first time the object is constructed (and bound to the constructor's prototype property that sets the created object's internal prototype chain) - so the private_method that is used is only the one that was created the first time.

Here is some sample code that will help illustrate what is going on:

  var global = 1;

  var Some_Class = function() {
    var private_method = 'whatever';
    var now = ++global;
    print("outer now: " + now );
    private_method = function(_some_value) {
        // private method implementation
        print("inner now: " + now);
    };

    if(!arguments.callee.prototype.public_method) {
        arguments.callee.prototype.public_method = function() {

            private_method.call(this, private_method);
        };
    }

    (function() {
        // constructor
    }).call(this)
}

new Some_Class().public_method(); // outer now: 2, inner now: 2
new Some_Class().public_method(); // outer now: 3, inner now: 2
new Some_Class().public_method(); // outer now: 4, inner now: 2

Are you sure that is what you want?

If your private_method does not need to refer to the enclosing object's state, then I see little benefit in doing things the way you are doing.

What I usually do (if i have to use 'new' to create my object) is the following:

function MyClass() {
  var private_var = 1; 
  function private_func()
  {

  }
  this.public_func = function() 
  {
     // do something
     private_func();
  }
  this.public_var = 10;
}

var myObj = new MyClass();

The downside to this approach is that each time you construct the object via 'new' you re-create all the closures. But unless my profiler tells me that this design choice needs to be optimized, i prefer its simplicity and clarity.

Also I don't see the benefit in your code of doing the following either:

  (function() { }).call(this);  // call the constructor

Why are you creating a separate scope in your constructor?

Problem

After reading a bit on Javascript's prototypical inheritance model, I change my style of constructing a class from ``` var Some_Class = function() { this.public_method = function() { }; (function() { // constructor }).call(this) } ``` to ``` var Some_Class = function() { (function() { // constructor }).call(this) } Some_Class.prototype.public_method = function() { }; ``` Although I understand that this is a good practice, but I am not allowed to access private methods from the public method anymore ``` var Some_Class = function() { var private_member = 'whatever'; (function() { // constructor }).call(this) } Some_Class.prototype.public_method = function() { return private_member; // not possible }; ``` After reading through an article here (Closure-created constructor), then I came out with this ``` var Some_Class = function() { var private_member = 'whatever', private_method = function(_some_value) { // private method implementation }; if(!arguments.callee.prototype.public_method) { arguments.callee.prototype.public_method = function() { private_method.call(this, private_method); }; } (function() { // constructor }).call(this) } ``` However, what are the drawbacks of doing this?! or is there a better way of doing this if I want to access private member in the public method?

Original source