7

Is there a correct way to create private static javascript variables (and functions) that do not change no matter how many times you create new Obj?

This is what I tried and it seems to work:

var ObjClass = (function(){

    var static_var = 0; //private static variable
    var static_fn = function(){ return static_var; }; //private static function

    return function(){
        ++static_var;
        var thisNumber = static_var;
        this.getThisNumber = function(){
             return thisNumber;
        }
        this.getStaticNumber = static_fn; //making static fn public
    }

})();

var obj1 = new ObjClass;
var obj2 = new ObjClass;
var obj3 = new ObjClass;

console.log(obj1.getThisNumber()); //output `1`
console.log(obj1.getStaticNumber()); //output `3`
console.log(obj2.getThisNumber()); //output `2`
console.log(obj2.getStaticNumber()); //output `3`
console.log(obj3.getThisNumber()); //output `3`
console.log(obj3.getStaticNumber()); //output `3`​

DEMO

Or is there some other better way?

15
  • static_var changes every time you create an object??? Commented May 31, 2012 at 13:12
  • you're missing the () after each call to new ObjClass. Commented May 31, 2012 at 13:13
  • @Bergi I mean they are the same from every class. Commented May 31, 2012 at 13:13
  • 1
    @jbabey you do not need it.... Commented May 31, 2012 at 13:14
  • 3
    This seems to be the widely-accepted way to implement statics in JS, yes. Commented May 31, 2012 at 13:14

2 Answers 2

6

Yes, that is the correct approach to create private static variables.

However, I would treat the static_fn different. It seems you want it to be public.

  1. It should be on your "class"es prototype as it does not interact with private instance variables
  2. It even does not interact with instances at all. The usual approach is to put such a function/variable on the "class" itself, i.e. the constructor in JS. As the constructor is a Function object, it can be extended with properties as any other js object.
var ObjClass = (function closure(){

    var static_var = 0; //static private (scoped) variable
    function static_fn(){ return static_var; }; //static private (scoped) function

    function ObjClass() {
        var thisNumber = ++static_var; // private instance variable
        this.getThisNumber = function() { // public instance method
            return thisNumber; // "privileged" to access scoped instance variables
        };
    }
    ObjClass.getStaticNumber = static_fn; // make the static_fn public
    return ObjClass;
})();



var obj1 = new ObjClass;
var obj2 = new ObjClass;
console.log(ObjClass.getStaticNumber()); //output `2`
var obj3 = new ObjClass;
console.log(ObjClass.getStaticNumber()); //output `3`

console.log(obj1.getThisNumber()); //output `1`
console.log(obj2.getThisNumber()); //output `2`
console.log(obj3.getThisNumber()); //output `3`
Sign up to request clarification or add additional context in comments.

5 Comments

--Bergi I changed my question and added the word private to the static idea. Yes, in my case the function is public, but the data static_var should still be private
+1 -- this seems to reflect better on how the object should be created :-) Thank you!
Yes, the static_var is private and can only accessed from inside the closure. From it you will "export" the public constructor function and the public, static getter function.
Bergi -- I do not think there is a reason for naming the closure function and the return function. What is your reason for doing so?
Just for talking to you about the "closure" function :-) Read kangax.github.com/nfe and leave it out.
1

I've previously used this trivial approach to create static variables, except that they're private.

function MyClass() {

    var static = this.constructor.static = this.constructor.static || {
        var1: defValue,
        ...
    }

    static.var1 = ... ;
}

i.e. just store the static variables as properties of the classes' primary constructor function.

7 Comments

Are there any advantages to this? And won't that make all of the statics public? Let us say I want one or two private static variables?
the statics here are kind of hidden, but you can't really have it both ways - it's hard (albeit not impossible) to have a variable both shared across multiple instances, yet also hidden in closure scope. You'd have to wrap an outer closure around the whole thing.
Well that is sort of what I do in my OP. And I think that @Bergi's post sums it up pretty well of what could be done.
@Neal the main advantage is simplicity.
@submind NB: ISTR that static is a reserved word in ES6, so use _static or similar.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.