Search code examples
javascriptobjectstatic-methodsstatic-members

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?


Solution

  • 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`