February 04, 2011

Static variables in JavaScript

Update: Please also read my second part on this topic.

Per standard JavaScript does not offer the possibility of declaring a variable as static. But we can utilize the fact that in JavaScript functions are functions and objects at the same time. This means that we can put a new attribute on the function object and use it as our "static" variable.

Let's see how that works:
var myFunction = function () {
    if (typeof myFunction.myStaticVar === 'undefined') {
        myFunction.myStaticVar = 0;
    }
    alert(myFunction.myStaticVar);
    myFunction.myStaticVar += 1;
};

In line 2 we check if that object attribute we want to use as our "static variable" already exists. If not, we create and initialize it with the numeric value zero (0).

Now every time we call myFunction() we alert the current value of staticVar and afterwards increment it by 1.

The effect is, that calling
myFunction();
myFunction();
myFunction();

will open 3 alert boxes:
0
1
2

Et voilĂ ! We just emulated a static variable in JavaScript.

4 comments:

  1. good explanation, but the code can be improved: in this way, the if() check is going to be executed everytime the function is called, while you only need it once for variable initialization.
    Suppose the function is going to be executed in a loop or in a critical part of the program, then current implementation it's not optimal.

    Moving the initialization outside function definition is the way to go:

    var myFunction = function () {
    // ...
    };
    myFunction.myStaticVar = 0;

    in this way we emphasize even more the "static" nature of myStaticVar.
    Hope this helps a bit :)

    ReplyDelete
  2. Thanks for your comment, Polaretto,
    you are absolutely right! I plan to do a second part on this topic. I will present your solution there ;-)

    Regards Benjamin

    ReplyDelete
  3. thank you very much for your appreciation, I'm glad it helped :)
    I used this "static variable" pattern very often for work projects, and found it very handy; it's especially effective if you're going to use a regular expression over and over in a function. Regexp istantiation can be costly sometimes, so you will just define it once as static, like this for example:

    function isNumeric(str){
     return isNumeric.re.test(str);
    }
    isNumeric.re = /\d+/;

    or with a closure if you prefer so:

    var isNumeric = (function (){
    var re = /\d+/;
    return function (str){
    return re.test(str);
    }
    })();

    I personally prefer the first approach ;)
    In this way you don't have a global regexp hanging around, and its role within the function is immediately clear upon reading the code.

    ReplyDelete
  4. yeah... I knew it was going to screw up formatting.
    Here's a more readable version:
    http://pastebay.com/114338

    ReplyDelete