Static variables in JavaScript
If you come from a class-based, statically typed object-oriented language (like Java, C++ or C#) I assume that you are trying to create a variable or method associated to a "type" but not to an instance.
An example using a "classical" approach, with constructor functions maybe could help you to catch the concepts of basic OO JavaScript:
function MyClass () { // constructor function var privateVariable = "foo"; // Private variable this.publicVariable = "bar"; // Public variable this.privilegedMethod = function () { // Public Method alert(privateVariable); };}// Instance method will be available to all instances but only load once in memory MyClass.prototype.publicMethod = function () { alert(this.publicVariable);};// Static variable shared by all instancesMyClass.staticProperty = "baz";var myInstance = new MyClass();
staticProperty
is defined in the MyClass object (which is a function) and has nothing to do with its created instances, JavaScript treats functions as first-class objects, so being an object, you can assign properties to a function.
UPDATE: ES6 introduced the ability to declare classes through the class
keyword. It is syntax sugar over the existing prototype-based inheritance.
The static
keyword allows you to easily define static properties or methods in a class.
Let's see the above example implemented with ES6 classes:
class MyClass { // class constructor, equivalent to // the function body of a constructor constructor() { const privateVariable = 'private value'; // Private variable at the constructor scope this.publicVariable = 'public value'; // Public property this.privilegedMethod = function() { // Public Method with access to the constructor scope variables console.log(privateVariable); }; } // Prototype methods: publicMethod() { console.log(this.publicVariable); } // Static properties shared by all instances static staticProperty = 'static value'; static staticMethod() { console.log(this.staticProperty); }}// We can add properties to the class prototypeMyClass.prototype.additionalMethod = function() { console.log(this.publicVariable);};var myInstance = new MyClass();myInstance.publicMethod(); // "public value"myInstance.additionalMethod(); // "public value"myInstance.privilegedMethod(); // "private value"MyClass.staticMethod(); // "static value"
You might take advantage of the fact that JS functions are also objects -- which means they can have properties.
For instance, quoting the example given on the (now vanished) article Static variables in Javascript:
function countMyself() { // Check to see if the counter has been initialized if ( typeof countMyself.counter == 'undefined' ) { // It has not... perform the initialization countMyself.counter = 0; } // Do something stupid to indicate the value alert(++countMyself.counter);}
If you call that function several time, you'll see the counter is being incremented.
And this is probably a much better solution than poluting the global namespace with a global variable.
And here is another possible solution, based on a closure : Trick to use static variables in javascript :
var uniqueID = (function() { var id = 0; // This is the private persistent value // The outer function returns a nested function that has access // to the persistent value. It is this nested function we're storing // in the variable uniqueID above. return function() { return id++; }; // Return and increment})(); // Invoke the outer function after defining it.
Which gets you the same kind of result -- except, this time, the incremented value is returned, instead of displayed.
You do it through an IIFE (immediately invoked function expression):
var incr = (function () { var i = 1; return function () { return i++; }})();incr(); // returns 1incr(); // returns 2