Naftali
Naftali

Reputation: 146310

Static variables in a Javascript class

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?

Upvotes: 7

Views: 5978

Answers (2)

Bergi
Bergi

Reputation: 664538

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`

Upvotes: 6

Alnitak
Alnitak

Reputation: 339816

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.

Upvotes: 1

Related Questions