Static variables in JavaScript

JavascriptVariablesStaticClosures

Javascript Problem Overview


How can I create static variables in Javascript?

Javascript Solutions


Solution 1 - 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 instances
MyClass.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 prototype
MyClass.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"

Solution 2 - Javascript

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 times, you'll see that 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.

Solution 3 - Javascript

You do it through an IIFE (immediately invoked function expression):

var incr = (function () {
    var i = 1;

    return function () {
        return i++;
    }
})();

incr(); // returns 1
incr(); // returns 2

Solution 4 - Javascript

I've seen a couple of similar answers, but I'd like to mention that this post describes it best, so I'd like to share it with you.

Here's some code taken from it, which I have modified to get a complete example which hopefully gives benefit to the community because it can be used as a design template for classes.

It also answers your question:

function Podcast() {

	// private variables
	var _somePrivateVariable = 123;

	// object properties (read/write)
	this.title = 'Astronomy Cast';
	this.description = 'A fact-based journey through the galaxy.';
	this.link = 'http://www.astronomycast.com';

	// for read access to _somePrivateVariable via immutableProp 
	this.immutableProp = function() {
	    return _somePrivateVariable;
	}

	// object function
	this.toString = function() {
	   return 'Title: ' + this.title;
	}
};

// static property
Podcast.FILE_EXTENSION = 'mp3';
// static function
Podcast.download = function(podcast) {
	console.log('Downloading ' + podcast + ' ...');
};

Given that example, you can access the static properties/function as follows:

// access static properties/functions
console.log(Podcast.FILE_EXTENSION);   // 'mp3'
Podcast.download('Astronomy cast');    // 'Downloading Astronomy cast ...'

And the object properties/functions simply as:

// access object properties/functions
var podcast = new Podcast();
podcast.title = 'The Simpsons';
console.log(podcast.toString());       // Title: The Simpsons
console.log(podcast.immutableProp());  // 123

Note that in podcast.immutableProp(), we have a closure: The reference to _somePrivateVariable is kept inside the function.

You can even define getters and setters. Take a look at this code snippet (where d is the object's prototype for which you want to declare a property, y is a private variable not visible outside of the constructor):

// getters and setters
var d = Date.prototype;
Object.defineProperty(d, "year", {
	get: function() {return this.getFullYear() },
	set: function(y) { this.setFullYear(y) }
});

It defines the property d.year via get and set functions - if you don't specify set, then the property is read-only and cannot be modified (be aware you will not get an error if you try to set it, but it has no effect). Each property has the attributes writable, configurable (allow to change after declaration) and enumerable (allow to use it as enumerator), which are per default false. You can set them via defineProperty in the 3rd parameter, e.g. enumerable: true.

What is also valid is this syntax:

// getters and setters - alternative syntax
var obj = {	a: 7, 
			get b() {return this.a + 1;}, 
			set c(x) {this.a = x / 2}
		};

which defines a readable/writable property a, a readonly property b and a write-only property c, through which property a can be accessed.

Usage:

console.log(obj.a); console.log(obj.b); // output: 7, 8
obj.c=40;
console.log(obj.a); console.log(obj.b); // output: 20, 21

Notes:

To avoid unexpected behaviour in case you've forgotten the new keyword, I suggest that you add the following to the function Podcast:

// instantiation helper
function Podcast() {
    if(false === (this instanceof Podcast)) {
        return new Podcast();
    }
// [... same as above ...]
};

Now both of the following instantiations will work as expected:

var podcast = new Podcast(); // normal usage, still allowed
var podcast = Podcast();     // you can omit the new keyword because of the helper

The 'new' statement creates a new object and copies all properties and methods, i.e.

var a=new Podcast();
var b=new Podcast();
a.title="a"; b.title="An "+b.title;
console.log(a.title); // "a"
console.log(b.title); // "An Astronomy Cast"

Note also, that in some situations it can be useful to use the return statement in the constructor function Podcast to return a custom object protecting functions the class internally relies on but which need to be exposed. This is explained further in chapter 2 (Objects) of the article series.

You can say that a and b inherit from Podcast. Now, what if you want to add a method to Podcast that applies to all of them after a and b have been instanciated? In this case, use the .prototype as follows:

Podcast.prototype.titleAndLink = function() {
    return this.title + " [" + this.link + "]";
};

Now call a and b again:

console.log(a.titleAndLink()); // "a [http://www.astronomycast.com]"
console.log(b.titleAndLink()); // "An Astronomy Cast [http://www.astronomycast.com]"

You can find more details about prototypes here. If you want to do more inheritance, I suggest looking into this.


The article series I've mentioned above are highly recommended to read, they include also the following topics:

  1. Functions
  2. Objects
  3. Prototypes
  4. Enforcing New on Constructor Functions
  5. Hoisting
  6. Automatic Semicolon Insertion
  7. Static Properties and Methods

Note that the automatic semicolon insertion "feature" of JavaScript (as mentioned in 6.) is very often responsible for causing strange issues in your code. Hence, I would rather regard it as a bug than as a feature.

If you want to read more, here is a quite interesting MSDN article about these topics, some of them described there provide even more details.

What is interesting to read as well (also covering the topics mentioned above) are those articles from the MDN JavaScript Guide:

If you want to know how to emulate c# out parameters (like in DateTime.TryParse(str, out result)) in JavaScript, you can find sample code here.


Those of you who are working with IE (which has no console for JavaScript unless you open the developer tools using F12 and open the console tab) might find the following snippet useful. It allows you to use console.log(msg); as used in the examples above. Just insert it before the Podcast function.

For your convenience, here's the code above in one complete single code snippet:

let console = { log: function(msg) {  
  let canvas = document.getElementById("log"), br = canvas.innerHTML==="" ? "" : "<br/>";
  canvas.innerHTML += (br + (msg || "").toString());
}};

console.log('For details, see the explaining text');

function Podcast() {

  // with this, you can instantiate without new (see description in text)
  if (false === (this instanceof Podcast)) {
    return new Podcast();
  }

  // private variables
  var _somePrivateVariable = 123;

  // object properties
  this.title = 'Astronomy Cast';
  this.description = 'A fact-based journey through the galaxy.';
  this.link = 'http://www.astronomycast.com';

  this.immutableProp = function() {
    return _somePrivateVariable;
  }

  // object function
  this.toString = function() {
    return 'Title: ' + this.title;
  }
};

// static property
Podcast.FILE_EXTENSION = 'mp3';
// static function
Podcast.download = function(podcast) {
  console.log('Downloading ' + podcast + ' ...');
};


// access static properties/functions
Podcast.FILE_EXTENSION; // 'mp3'
Podcast.download('Astronomy cast'); // 'Downloading Astronomy cast ...'

// access object properties/functions
var podcast = new Podcast();
podcast.title = 'The Simpsons';
console.log(podcast.toString()); // Title: The Simpsons
console.log(podcast.immutableProp()); // 123

// getters and setters
var d = Date.prototype;
Object.defineProperty(d, "year", {
  get: function() {
    return this.getFullYear()
  },
  set: function(y) {
    this.setFullYear(y)
  }
});

// getters and setters - alternative syntax
var obj = {
  a: 7,
  get b() {
    return this.a + 1;
  },
  set c(x) {
    this.a = x / 2
  }
};

// usage:
console.log(obj.a); console.log(obj.b); // output: 7, 8
obj.c=40;
console.log(obj.a); console.log(obj.b); // output: 20, 21

var a=new Podcast();
var b=new Podcast();
a.title="a"; b.title="An "+b.title;
console.log(a.title); // "a"
console.log(b.title); // "An Astronomy Cast"

Podcast.prototype.titleAndLink = function() {
    return this.title + " [" + this.link + "]";
};
    
console.log(a.titleAndLink()); // "a [http://www.astronomycast.com]"
console.log(b.titleAndLink()); // "An Astronomy Cast [http://www.astronomycast.com]"

<div id="log"></div>


Notes:

  • Some good tips, hints and recommendations about JavaScript programming in general you can find here (JavaScript best practices) and there ('var' versus 'let'). Also recommended is this article about implicit typecasts (coercion).

  • A convenient way to use classes and compile them into JavaScript is TypeScript. Here is a playground where you can find some examples showing you how it works. Even if you're not using TypeScript at the moment, you can have a look because you can compare TypeScript with the JavaScript result on a side-by-side view. Most examples are simple, but there is also a Raytracer example which you can try out instantly. I recommend especially looking into the "Using Classes", "Using Inheritance" and "Using Generics" examples by selecting them in the combobox - these are nice templates you can instantly use in JavaScript. Typescript is used with Angular.

  • To achieve encapsulation of local variables, functions etc in JavaScript, I suggest to use a pattern like the following (JQuery uses the same technique):

<html>
<head></head>
<body><script>
    'use strict';
    // module pattern (self invoked function)
    const myModule = (function(context) { 
    // to allow replacement of the function, use 'var' otherwise keep 'const'

      // put variables and function with local module scope here:
      var print = function(str) {
        if (str !== undefined) context.document.write(str);
        context.document.write("<br/><br/>");
        return;
      }
      // ... more variables ...

      // main method
      var _main = function(title) {

        if (title !== undefined) print(title);
        print("<b>last modified:&nbsp;</b>" + context.document.lastModified + "<br/>");        
        // ... more code ...
      }

      // public methods
      return {
        Main: _main
        // ... more public methods, properties ...
      };

    })(this);

    // use module
    myModule.Main("<b>Module demo</b>");
</script></body>
</html>

Of course, you can - and should - put the script code in a separate *.js file; this is just written inline to keep the example short.

Self-invocing functions (also known as IIFE = Immediately Invoked Function Expression) are described in more detail here.

Solution 5 - Javascript

you can use arguments.callee to store "static" variables (this is useful in anonymous function too):

function () {
  arguments.callee.myStaticVar = arguments.callee.myStaticVar || 1;
  arguments.callee.myStaticVar++;
  alert(arguments.callee.myStaticVar);
}

Solution 6 - Javascript

Updated answer:

In ECMAScript 6, you can create static functions using the static keyword:

class Foo {
  
  static bar() {return 'I am static.'}

}

//`bar` is a property of the class
Foo.bar() // returns 'I am static.'

//`bar` is not a property of instances of the class
var foo = new Foo()
foo.bar() //-> throws TypeError

ES6 classes don't introduce any new semantics for statics. You can do the same thing in ES5 like this:

//constructor
var Foo = function() {}

Foo.bar = function() {
    return 'I am static.'
}

Foo.bar() // returns 'I am static.'

var foo = new Foo()
foo.bar() // throws TypeError

You can assign to a property of Foo because in JavaScript functions are objects.

Solution 7 - Javascript

function Person(){
  if(Person.count == undefined){
    Person.count = 1;
  }
  else{
    Person.count ++;
  }
  console.log(Person.count);
}

var p1 = new Person();
var p2 = new Person();
var p3 = new Person();

Solution 8 - Javascript

The following example and explanation are from the book Professional JavaScript for Web Developers 2nd Edition by Nicholas Zakas. This is the answer I was looking for so I thought it would be helpful to add it here.

(function () {
    var name = '';
    Person = function (value) {
        name = value;
    };
    Person.prototype.getName = function () {
        return name;
    };
    Person.prototype.setName = function (value) {
        name = value;
    };
}());
var person1 = new Person('Nate');
console.log(person1.getName()); // Nate
person1.setName('James');
console.log(person1.getName()); // James
person1.name = 'Mark';
console.log(person1.name); // Mark
console.log(person1.getName()); // James
var person2 = new Person('Danielle');
console.log(person1.getName()); // Danielle
console.log(person2.getName()); // Danielle

The Person constructor in this example has access to the private variable name, as do the getName() and setName() methods. Using this pattern, the name variable becomes static and will be used among all instances. This means calling setName() on one instance affects all other instances. Calling setName() or creating a new Person instance sets the name variable to a new value. This causes all instances to return the same value.

Solution 9 - Javascript

If you are using the new class syntax then you can now do the following:

    class MyClass {
      static get myStaticVariable() {
        return "some static variable";
      }
    }

    console.log(MyClass.myStaticVariable);

    aMyClass = new MyClass();
    console.log(aMyClass.myStaticVariable, "is undefined");

This effectively creates a static variable in JavaScript.

Solution 10 - Javascript

About the class introduced by ECMAScript 2015. The other answers are not totally clear.

Here is an example showing how to create a static var staticVar with the ClassName.var synthax:

class MyClass {
    constructor(val) {
        this.instanceVar = val;
        MyClass.staticVar = 10;
    }
}

var class1 = new MyClass(1);
console.log(class1.instanceVar);      // 1
console.log(class1.constructor.staticVar); // 10

// New instance of MyClass with another value
var class2 = new MyClass(3);
console.log(class1.instanceVar);      // 1
console.log(class2.instanceVar);      // 3

To access the static variable we use the .constructor property that returns a reference to the object constructor function that created the class. We can call it on the two created instances:

MyClass.staticVar = 11;
console.log(class1.constructor.staticVar); // 11
console.log(class2.constructor.staticVar); // 11 <-- yes it's static! :)

MyClass.staticVar = 12;
console.log(class1.constructor.staticVar); // 12
console.log(class2.constructor.staticVar); // 12

Solution 11 - Javascript

If you want to declare static variables for creating constants in your application then I found following as most simplistic approach

ColorConstants = (function()
{
    var obj = {};
    obj.RED = 'red';
    obj.GREEN = 'green';
    obj.BLUE = 'blue';
    obj.ALL = [obj.RED, obj.GREEN, obj.BLUE];
    return obj;
})();

//Example usage.
var redColor = ColorConstants.RED;

Solution 12 - Javascript

There are other similar answers, but none of them quite appealed to me. Here's what I ended up with:

var nextCounter = (function () {
  var counter = 0;
  return function() {
    var temp = counter;
    counter += 1;
    return temp;
  };
})();

Solution 13 - Javascript

In addition to the rest, there's currently a draft (stage-2 proposal) on ECMA Proposals that introduces static public fields in classes. (private fields were considered)

Using the example from the proposal, the proposed static syntax will look like this:

class CustomDate {
  // ...
  static epoch = new CustomDate(0);
}

and be equivalent to the following which others have highlighted:

class CustomDate {
  // ...
}
CustomDate.epoch = new CustomDate(0);

You can then access it via CustomDate.epoch.

You can keep track of the new proposal in proposal-static-class-features.


Currently, babel supports this feature with the transform class properties plugin which you can use. Additionally, though still in progress, V8 is implementing it.

Solution 14 - Javascript

You can create a static variable in JavaScript like this below. Here count is the static variable.

var Person = function(name) {
  this.name = name;
  // first time Person.count is undefined, so it is initialized with 1
  // next time the function is called, the value of count is incremented by 1
  Person.count = Person.count ? Person.count + 1 : 1;
}

var p1 = new Person('User p1');
console.log(p1.constructor.count);   // prints 1
var p2 = new Person('User p2');
console.log(p2.constructor.count);   // prints 2

You can assign values to the static variable using either the Person function, or any of the instances:

// set static variable using instance of Person
p1.constructor.count = 10;         // this change is seen in all the instances of Person
console.log(p2.constructor.count); // prints 10

// set static variable using Person
Person.count = 20;
console.log(p1.constructor.count); // prints 20

Solution 15 - Javascript

There are 4 ways to emulate function-local static variables in Javascript.

Method 1: Using function object properties (supported in old browsers)

function someFunc1(){
	if( !('staticVar' in someFunc1) )
		someFunc1.staticVar = 0 ;
	alert(++someFunc1.staticVar) ;
}

someFunc1() ; //prints 1
someFunc1() ; //prints 2
someFunc1() ; //prints 3

Method 2: Using a closure, variant 1 (supported in old browsers)

var someFunc2 = (function(){
	var staticVar = 0 ;
	return function(){
		alert(++staticVar) ;
	}
})()

someFunc2() ; //prints 1
someFunc2() ; //prints 2
someFunc2() ; //prints 3

Method 3: Using a closure, variant 2 (also supported in old browsers)

var someFunc3 ;
with({staticVar:0})
	var someFunc3 = function(){
		alert(++staticVar) ;
	}

someFunc3() ; //prints 1
someFunc3() ; //prints 2
someFunc3() ; //prints 3

Method 4: Using a closure, variant 3 (requires support for EcmaScript 2015)

{
	let staticVar = 0 ;
	function someFunc4(){
		alert(++staticVar) ;
	}
}

someFunc4() ; //prints 1
someFunc4() ; //prints 2
someFunc4() ; //prints 3

Solution 16 - Javascript

If you wanted to make a global static variable:

var my_id = 123;

Replace the variable with the below:

Object.defineProperty(window, 'my_id', {
	get: function() {
			return 123;
		},
	configurable : false,
	enumerable : false
});

Solution 17 - Javascript

The closest thing in JavaScript to a static variable is a global variable - this is simply a variable declared outside the scope of a function or object literal:

var thisIsGlobal = 1;

function foo() {
    var thisIsNot = 2;
}

The other thing you could do would be to store global variables inside an object literal like this:

var foo = { bar : 1 }

And then access the variabels like this: foo.bar.

Solution 18 - Javascript

There's another approach, which solved my requirements after browsing this thread. It depends on exactly what you want to achieve with a "static variable".

The global property sessionStorage or localStorage allows data to be stored for the life of the session, or for an indefinite longer period until explicitly cleared, respectively. This allows data to be shared among all windows, frames, tab panels, popups etc of your page/app and is much more powerful than a simple "static/global variable" in one code segment.

It avoids all hassle with the scope, lifetime, semantics, dynamics etc of top-level global variables, ie Window.myglobal. Don't know how efficient it is, but that's not important for modest amounts of data, accessed at modest rates.

Easily accessed as "sessionStorage.mydata = anything" and retrieved similarly. See "JavaScript: The Definitive Guide, Sixth Edition", David Flanagan, ISBN: 978-0-596-80552-4, Chapter 20, section 20.1. This is easily downloadable as a PDF by simple search, or in your O'Reilly Safaribooks subscription (worth its weight in gold).

Solution 19 - Javascript

To condense all class concepts here, test this:

var Test = function() {
  // "super private" variable, accessible only here in constructor. There are no real private variables
  //if as 'private' we intend variables accessible only by the class that defines the member and NOT by child classes
  var test_var = "super private";

  //the only way to access the "super private" test_var is from here
  this.privileged = function(){
    console.log(test_var);
  }();

  Test.test_var = 'protected';//protected variable: accessible only form inherited methods (prototype) AND child/inherited classes

  this.init();
};//end constructor

Test.test_var = "static";//static variable: accessible everywhere (I mean, even out of prototype, see domready below)

Test.prototype = {

 init:function(){
   console.log('in',Test.test_var);
 }

};//end prototype/class


//for example:
$(document).ready(function() {

 console.log('out',Test.test_var);

 var Jake = function(){}

 Jake.prototype = new Test();

 Jake.prototype.test = function(){
   console.log('jake', Test.test_var);
 }

 var jake = new Jake();

 jake.test();//output: "protected"

});//end domready

Well, another way to take a look to best practices in these things, is to just see how coffeescript translates these concepts.

#this is coffeescript
class Test
 #static
 @prop = "static"

 #instance
 constructor:(prop) ->
   @prop = prop
   console.log(@prop)

 t = new Test('inst_prop');

 console.log(Test.prop);


//this is how the above is translated in plain js by the CS compiler
  Test = (function() {
    Test.prop = "static";

    function Test(prop) {
     this.prop = prop;
     console.log(this.prop);
    }

    return Test;

  })();

  t = new Test('inst_prop');

  console.log(Test.prop);

Solution 20 - Javascript

2021 UPDATE

In 2021 you can simply use the static keyword

TC39 moved the STATIC keyword to being Stage-4 Language Feature as of APRIL, 2021. It took a long time to make the static JS features an official set of JS language features, the wait was due to lacking browser support, however; Major browsers now support the static keyword, and its open season for public static fields & private static fields.



Below is a generalized example of what the new way to implement static JavaScript class members looks like
class ColorFinder {
  static #red = "#ff0000";
  static #green = "#00ff00";
  static #blue = "#0000ff";
  
  static colorName(name) {
    switch (name) {
      case "red": return ColorFinder.#red;
      case "blue": return ColorFinder.#blue;
      case "green": return ColorFinder.#green;
      default: throw new RangeError("unknown color");
    }
  }
  
  // Somehow use colorName
}

Example above was taken from the TC39 Repository, Static-Fields


To read more about the implementation of this new JS language feature (CLICK HERE).
To read more about the feature itself, as well as seeing examples that demonstarte the syntax used for static fields (CLICK HERE).

Solution 21 - Javascript

In JavaScript variables are static by default. Example:

var x = 0;

function draw() {
    alert(x); //
    x+=1;
}

setInterval(draw, 1000);

The value of x is incremented by 1 every 1000 milliseconds
It will print 1,2,3 so forth

Solution 22 - Javascript

Function's / classes allows only single constructor for its object scope. Function Hoisting, declarations & expressions > * Functions created with the Function constructor do not create closures to their creation contexts; they always are created in the global scope. > > var functionClass = function ( ) { var currentClass = Shape; _inherits(currentClass, superClass); function functionClass() { superClass.call(this); // Linking with SuperClass Constructor. // Instance Variables list. this.id = id; return this; } }(SuperClass)

Closures - closure's copies are function with preserved data. > * Each closure's copies are created to a function with their own free values or references, Whenever you use function inside another function, a closure is used. > * A closure in JavaScript is like maintaining a copy of all the local variables of its parent function by the innerFunctions. > > function closureFun( args ) { // Local variable that ends up within closure var num = args; num++; return function() { console.log(num); } } var closure1 = closureFun( 5 ); var closure2 = closureFun( 777 ); closure1(); // 5 closure2(); // 777 closure2(); // 778 closure1(); // 6


ES5 Function Classes: uses Object.defineProperty ( O, P, Attributes )

> The Object.defineProperty() method defines a new property directly on an object, or modifies an existing property on an object, and returns the object.

Created some methods by using ``, So that every once can understand the function classes easily.

'use strict';
var Shape = function ( superClass ) {
	var currentClass = Shape;
	_inherits(currentClass, superClass); // Prototype Chain - Extends
	
	function Shape(id) { superClass.call(this); // Linking with SuperClass Constructor.
		// Instance Variables list.
		this.id = id;	return this;
	}
	var staticVariablesJOSN = { "parent_S_V" : 777 };
	staticVariable( currentClass, staticVariablesJOSN );
	
	// Setters, Getters, instanceMethods. [{}, {}];
	var instanceFunctions = [
		{
			key: 'uniqueID',
			get: function get() { return this.id; },
			set: function set(changeVal) { this.id = changeVal; }
		}
	];
	instanceMethods( currentClass, instanceFunctions );
	
	return currentClass;
}(Object);

var Rectangle = function ( superClass ) {
	var currentClass = Rectangle;
	
	_inherits(currentClass, superClass); // Prototype Chain - Extends

	function Rectangle(id, width, height) { superClass.call(this, id); // Linking with SuperClass Constructor.

		this.width = width;
		this.height = height;	return this;
	}

	var staticVariablesJOSN = { "_staticVar" : 77777 };
	staticVariable( currentClass, staticVariablesJOSN );

	var staticFunctions = [
		{
			key: 'println',
			value: function println() { console.log('Static Method'); }
		}
	];
	staticMethods(currentClass, staticFunctions);
	
	var instanceFunctions = [
		{
			key: 'setStaticVar',
			value: function setStaticVar(staticVal) {
				currentClass.parent_S_V = staticVal;
				console.log('SET Instance Method Parent Class Static Value : ', currentClass.parent_S_V);
			}
		}, {
			key: 'getStaticVar',
			value: function getStaticVar() {
				console.log('GET Instance Method Parent Class Static Value : ', currentClass.parent_S_V);
				return currentClass.parent_S_V;
			}
		}, {
			key: 'area',
			get: function get() {
				console.log('Area : ', this.width * this.height);
				return this.width * this.height;
				}
		}, {
			key: 'globalValue',
			get: function get() {
				console.log('GET ID : ', currentClass._staticVar);
				return currentClass._staticVar;
			},
			set: function set(value) {
				currentClass._staticVar = value;
				console.log('SET ID : ', currentClass._staticVar);
			}
		}
	];
	instanceMethods( currentClass, instanceFunctions );
	
	return currentClass;
}(Shape);

// ===== ES5 Class Conversion Supported Functions =====
function defineProperties(target, props) {
	console.log(target, ' : ', props);
	for (var i = 0; i < props.length; i++) {
		var descriptor = props[i];
		descriptor.enumerable = descriptor.enumerable || false;
		descriptor.configurable = true;
		if ("value" in descriptor) descriptor.writable = true;
		Object.defineProperty(target, descriptor.key, descriptor);
	}
}
function staticMethods( currentClass, staticProps ) {
	defineProperties(currentClass, staticProps);
};
function instanceMethods( currentClass, protoProps ) {
	defineProperties(currentClass.prototype, protoProps);
};
function staticVariable( currentClass, staticVariales ) {
	// Get Key Set and get its corresponding value.
	// currentClass.key = value;
	for( var prop in staticVariales ) {
		console.log('Keys : Values');
		if( staticVariales.hasOwnProperty( prop ) ) {
			console.log(prop, ' : ', staticVariales[ prop ] );
			currentClass[ prop ] = staticVariales[ prop ];
		}
	}
};
function _inherits(subClass, superClass) {
	console.log( subClass, ' : extends : ', superClass );
	if (typeof superClass !== "function" && superClass !== null) {
		throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
	}
	subClass.prototype = Object.create(superClass && superClass.prototype, 
			{ constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });
	if (superClass)
		Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}

Below code snippet is to test about Each instance has their own copy of instance members and common static members.

var objTest = new Rectangle('Yash_777', 8, 7);
console.dir(objTest);

var obj1 = new Rectangle('R_1', 50, 20);
Rectangle.println(); // Static Method
console.log( obj1 );    // Rectangle {id: "R_1", width: 50, height: 20}
obj1.area;              // Area :  1000
obj1.globalValue;       // GET ID :  77777
obj1.globalValue = 88;  // SET ID :  88
obj1.globalValue;       // GET ID :  88  

var obj2 = new Rectangle('R_2', 5, 70);
console.log( obj2 );    // Rectangle {id: "R_2", width: 5, height: 70}
obj2.area;              // Area :  350    
obj2.globalValue;       // GET ID :  88
obj2.globalValue = 999; // SET ID :  999
obj2.globalValue;       // GET ID :  999

console.log('Static Variable Actions.');
obj1.globalValue;        // GET ID :  999

console.log('Parent Class Static variables');
obj1.getStaticVar();    // GET Instance Method Parent Class Static Value :  777
obj1.setStaticVar(7);   // SET Instance Method Parent Class Static Value :  7
obj1.getStaticVar();    // GET Instance Method Parent Class Static Value :  7

> Static method calls are made directly on the class and are not callable on instances of the class. But you can achieve the calls for static members from inside an instance.

> Using syntax:

> this.constructor.staticfunctionName();

class MyClass {
	constructor() {}
	static staticMethod() {
		console.log('Static Method');
	}
}
MyClass.staticVar = 777;

var myInstance = new MyClass();
// calling from instance
myInstance.constructor.staticMethod();
console.log('From Inside Class : ',myInstance.constructor.staticVar);

// calling from class
MyClass.staticMethod();
console.log('Class : ', MyClass.staticVar);

ES6 Classes: ES2015 classes are a simple sugar over the prototype-based OO pattern. Having a single convenient declarative form makes class patterns easier to use, and encourages interoperability. Classes support prototype-based inheritance, super calls, instance and static methods and constructors.

Example: refer my previous post.

Solution 23 - Javascript

You can define static functions in JavaScript using the static keyword:

class MyClass {
  static myStaticFunction() {
    return 42;
  }
}

MyClass.myStaticFunction(); // 42

As of this writing, you still can't define static properties (other than functions) within the class. Static properties are still a Stage 3 proposal, which means they aren't part of JavaScript yet. However, there's nothing stopping you from simply assigning to a class like you would to any other object:

class MyClass {}

MyClass.myStaticProperty = 42;

MyClass.myStaticProperty; // 42

Final note: be careful about using static objects with inheritance - all inherited classes share the same copy of the object.

Solution 24 - Javascript

Window level vars are sorta like statics in the sense that you can use direct reference and these are available to all parts of your app

Solution 25 - Javascript

Working with MVC websites that use jQuery, I like to make sure AJAX actions within certain event handlers can only be executed once the previous request has completed. I use a "static" jqXHR object variable to achieve this.

Given the following button:

<button type="button" onclick="ajaxAction(this, { url: '/SomeController/SomeAction' })">Action!</button>

I generally use an IIFE like this for my click handler:

var ajaxAction = (function (jqXHR) {
    return function (sender, args) {
        if (!jqXHR || jqXHR.readyState == 0 || jqXHR.readyState == 4) {
            jqXHR = $.ajax({
                url: args.url,
                type: 'POST',
                contentType: 'application/json',
                data: JSON.stringify($(sender).closest('form').serialize()),
                success: function (data) {
                    // Do something here with the data.
                }
            });
        }
    };
})(null);

Solution 26 - Javascript

If you want to use prototype then there is a way

var p = function Person() {
    this.x = 10;
    this.y = 20;
}
p.prototype.counter = 0;
var person1 = new p();
person1.prototype = p.prototype;
console.log(person1.counter);
person1.prototype.counter++;
var person2 = new p();
person2.prototype = p.prototype;
console.log(person2.counter);
console.log(person1.counter);

Doing this you will be able to access the counter variable from any instance and any change in the property will be immediately reflected!!

Solution 27 - Javascript

So what I see with the other answers is that they don't address the fundamental architectural requirement of a static attribute in object oriented programming.

Object oriented programming actually has two different styles one is 'class based' (C++, C#, Java etc), the other is 'prototypal' (Javascript). In class based languages a 'static attribute' is supposed to be associated with the class and not the instantiated objects. This concept actually works much more intuitively in a prototypal languages like Javascript because you just assign the attribute as a value of the parent prototype like so.

function MyObject() {};
MyObject.prototype.staticAttribute = "some value";

And access it from every one of the objects that is instantiated from this constructor like so...

var childObject1 = new MyObject(); // Instantiate a child object
var childObject2 = new MyObject(); // Instantiate another child object
console.log(childObject.staticAttribute); // Access the static Attribute from child 1
console.log(childObject.staticAttribute); // Access the static Attribute from child 2

Now if you go ahead and change the MyObject.prototype.staticAttribute the change will cascade down to the child objects that immediately inherit it.

However there are a few 'gotchas' that could significantly undermine the 'static' nature of this attribute, or just leave security vulnerability...

First make sure to hide the constructor from the Global namespace by enclosing it inside another function like the jQuery ready method

 $(document).ready(function () {
    function MyObject() {
        // some constructor instructions
    };
    MyObject.prototype.staticAttribute = "some value";
    var childObject = new MyObject(); // instantiate child object
    console.log(childObject.staticAttribute); // test attribute
});

Second and lastly, even if you do this, the attribute is still editable from any of the other parts of your own script, so it could be the case that a bug in your code writes over the attribute on one of the child objects and detaches it from the parent prototype, so if you change the parent attribute it will no longer cascade and change the static attribute for the child object. See this jsfiddle. In different scenarios we could either Object.freeze(obj) to stop any changes to the child object, or we could set up a setter and getter method in the constructor and access a closure, both of these have associated complexities.

It seems to me that there is not a perfect analogue between the class-based idea of a 'static attribute' and this Javascript implementation. So I think it might be better in the long run to use a different code pattern that is more Javascript friendly. Such as a central datastore or cache or even a dedicated helper object to hold all the necessary static variables.

Solution 28 - Javascript

I didn't see this idea in any of the answers so just adding it to the list. If it's a duplicate just let me know and i'll delete it and upvote the other.

I created a sort of super global in my website. Since I have several js files that are loaded on every page load and dozens of other js files that are only loaded on some pages I put all of the "global" function into a single global variable.

At the top of my first included "global" files is the declaration

var cgf = {}; // Custom global functions.

Then I delcare several global helper functions

cgf.formBehaviors = function()
{
    // My form behaviors that get attached in every page load.
}

Then if I need a static variable I just store it outside scope such as outside the document ready or outside the behavior attachment. (I use jquery but it should work in javascript)

cgf.first = true;
$.on('click', '.my-button', function()
{
    // Don't allow the user to press the submit twice.
    if (cgf.first)
    {
        // first time behavior. such as submit
    }
    cgf.first = false;
}

This of course is a global not a static but as it is reinitialized on every page load it accomplishes the same purpose.

Solution 29 - Javascript

In JavaScript, there is no term or keyword static, but we can put such data directly into function object (like in any other object).

function f() {
    f.count = ++f.count || 1 // f.count is undefined at first
    alert("Call No " + f.count)
}

f(); // Call No 1

f(); // Call No 2

Solution 30 - Javascript

For private static variables, I found this way:

function Class()
{
}

Class.prototype = new function()
{
    _privateStatic = 1;
    this.get = function() { return _privateStatic; }
    this.inc = function() { _privateStatic++; }
};

var o1 = new Class();
var o2 = new Class();

o1.inc();

console.log(o1.get());
console.log(o2.get()); // 2

Solution 31 - Javascript

Try this one:

If we define a property and override its getters and setters to use the Function Object property then in theory you can have an static variable in javascript

for example:

function Animal() {
    if (isNaN(this.totalAnimalCount)) {
        this.totalAnimalCount = 0;
    }
    this.totalAnimalCount++;
};
Object.defineProperty(Animal.prototype, 'totalAnimalCount', {
    get: function() {
        return Animal['totalAnimalCount'];
    },
   set: function(val) {
       Animal['totalAnimalCount'] = val;
   }
});
var cat = new Animal(); 
console.log(cat.totalAnimalCount); //Will produce 1
var dog = new Animal();
console.log(cat.totalAnimalCount); //Will produce 2 and so on.

Solution 32 - Javascript

In JavaScript everything is either a primitive type or an object. Functions are objects — (key value pairs).

When you create a function you create two objects. One object that represents the function itself and the other that represents the prototype of the function.

Function is basically in that sense an object with the properties:

function name, 
arguments length 
and the functional prototype.

So where to set the static property: Two places, either inside the function object or inside the function prototype object.

Here is a snippet that creates that end even instantiates two instances, using the new JavaScript keyword.

function C () { // function
  var privateProperty = "42";  
  this.publicProperty = "39";  
  
  this.privateMethod = function(){ 
   console.log(privateProperty);
  };
}

C.prototype.publicMethod = function () {    
  console.log(this.publicProperty);
};

C.prototype.staticPrototypeProperty = "4";
C.staticProperty = "3";


var i1 = new C(); // instance 1
var i2 = new C(); // instance 2

i1.privateMethod();
i1.publicMethod();

console.log(i1.__proto__.staticPrototypeProperty);
i1.__proto__.staticPrototypeProperty = "2";
console.log(i2.__proto__.staticPrototypeProperty);

console.log(i1.__proto__.constructor.staticProperty);
i1.__proto__.constructor.staticProperty = "9";
console.log(i2.__proto__.constructor.staticProperty);

The main idea is that instances i1 and i2 are using the same static properties.

Solution 33 - Javascript

I use static function variables a lot and it's a real shame JS doesn't have a built-in mechanism for that. Too often I see code where variables and functions are defined in an outer scope even though they're just used inside one function. This is ugly, error prone and just asking for trouble...

I came up with the following method:

if (typeof Function.prototype.statics === 'undefined') {
  Function.prototype.statics = function(init) {
    if (!this._statics) this._statics = init ? init() : {};
	return this._statics;
  }
}

This adds a 'statics' method to all functions (yes, just relax about it), when called it will add an empty object (_statics) to the function object and return it. If an init function is supplied _statics will be set to init() result.

You can then do:

function f() {
  const _s = f.statics(() => ({ v1=3, v2=somefunc() });

  if (_s.v1==3) { ++_s.v1; _s.v2(_s.v1); }
} 

Comparing this to an IIFE which is the other correct answer, this has the disadvantage of adding one assignment and one if on every function call and adding a '_statics' member to the function, however there are a few advantages: the arguments are there at the top not in the internal function, using a 'static' in the internal function code is explicit with an '_s.' prefix, and it is overall simpler to look at and understand.

Solution 34 - Javascript

Summary:

In ES6/ES 2015 the class keyword was introduced with an accompanied static keyword. Keep in mind that this is syntactic sugar over the prototypal inheritance model which javavscript embodies. The static keyword works in the following way for methods:

class Dog {

  static bark () {console.log('woof');}
  // classes are function objects under the hood
  // bark method is located on the Dog function object
  
  makeSound () { console.log('bark'); }
  // makeSound is located on the Dog.prototype object

}

// to create static variables just create a property on the prototype of the class
Dog.prototype.breed = 'Pitbull';

// So to define a static property we don't need the static keyword.

const fluffy = new Dog();
const vicky = new Dog();
console.log(fluffy.breed, vicky.breed);

// changing the static variable changes it on all the objects
Dog.prototype.breed = 'Terrier';
console.log(fluffy.breed, vicky.breed);

Solution 35 - Javascript

I normally use this method for 2 main reasons:

if I want to store functions local values, I use something like "Local.x", "Local.y", "Local.TempData", etc ...!

If I want to store functions static values, I use something like "Static.o", "Static.Info", "Static.count", etc ...!

[Update2]: Same method, but uses IIFE approach!

[Update1]: "Static" and "Local" objects For Functions are created automatically By Pre-Editing Scripts!

Solution 36 - Javascript

I used the prototype and that way it worked:

class Cat {
  constructor() {
    console.log(Cat.COLLECTION_NAME);
  }
}

Cat.COLLECTION_NAME = "cats";

or using an static getter:

class Cat {
  constructor() {
    console.log(Cat.COLLECTION_NAME);
  }

  static get COLLECTION_NAME() {
    return "cats"
  }
}

Solution 37 - Javascript

I have universal method:

  • create object like: stat_flags = {};
  • use it with adding fields on the fly: flags.popup_save_inited = true;
  • next time ask is there flag you need in the object and do your logic

Example:

class ACTGeneratedPages {
    constructor(table_data, html_table_id) {
        this.flags = {};//static flags for any processes
		
		//any your code here
		
    }

    call_popup(post_id) {

        let _this = this;
        document.getElementById('act-popup-template').style.display = 'block';

        if (!this.flags.popup_save_inited) {//second time listener will not be attached
            document.querySelector('.act-modal-save').addEventListener('click', function (e) {
                //saving data code here
                return false;
            });
        }
        
        this.flags.popup_save_inited = true;//set flag here
    }

}

Solution 38 - Javascript

ES6 classes support static functions that behave much like static functions in other object-oriented languages:

class MyClass {
  static myFunction() {
    return 42;
  }
}

typeof MyClass.myFunction; // 'function'
MyClass.myFunction(); // 42

General static properties are still a stage 3 proposal, which means you need Babel's stage 3 preset to use them. But with Babel, you can do this:

class MyClass {
  static answer = 42;
}

MyClass.answer; // 42

Solution 39 - Javascript

you can reassign the function after static variables have been declared

function IHaveBeenCalled() {
  console.log("YOU SHOULD ONLY SEE THIS ONCE");
  return "Hello World: "
}
function testableFunction(...args) {
  testableFunction=inner //reassign the function
  const prepend=IHaveBeenCalled()
  return inner(...args) //pass all arguments the 1st time
  function inner(num) {
    console.log(prepend + num);
  }
}
testableFunction(2) // Hello World: 2
testableFunction(5) // Hello World: 5

this uses ...args which is slower, is there a way to use scope of parent function for the 1st time instead of passing all arguments ?


my use case:

function copyToClipboard(...args) {
  copyToClipboard = inner //reassign the function
  const child_process = require('child_process')
  return inner(...args) //pass all arguments the 1st time
  function inner(content_for_the_clipboard) {
    child_process.spawn('clip').stdin.end(content_for_the_clipboard)
  }
}

if you want to use child_process outside of scope, you can assign it to a property of copyToClipboard

function copyToClipboard(...args) {
  copyToClipboard = inner //reassign the function
  copyToClipboard.child_process = require('child_process')
  return inner(...args) //pass all arguments the 1st time
  function inner(content_for_the_clipboard) {
    copyToClipboard.child_process.spawn('clip').stdin.end(content_for_the_clipboard)
  }
}

Solution 40 - Javascript

There is no such thing as an static variable in Javascript. This language is prototype-based object orientated, so there are no classes, but prototypes from where objects "copy" themselves.

You may simulate them with global variables or with prototyping (adding a property to the prototype):

function circle(){
}
circle.prototype.pi=3.14159

Solution 41 - Javascript

'Class' System

var Rect = (function(){
    'use strict';
     return {
        instance: function(spec){
            'use strict';
            spec = spec || {};

            /* Private attributes and methods */
            var x = (spec.x === undefined) ? 0 : spec.x,
            y = (spec.x === undefined) ? 0 : spec.x,
            width = (spec.width === undefined) ? 1 : spec.width,
            height = (spec.height === undefined) ? 1 : spec.height;
        
            /* Public attributes and methods */
            var that = { isSolid: (spec.solid === undefined) ? false : spec.solid };

            that.getX = function(){ return x; };
            that.setX = function(value) { x = value; };
        
            that.getY = function(){ return y; };
            that.setY = function(value) { y = value; };

            that.getWidth = function(){ return width; };
            that.setWidth = function(value) { width = value; };

            that.getHeight = function(){ return height; };
            that.setHeight = function(value) { height = value; };

            return that;
        },

        copy: function(obj){
            return Rect.instance({ x: obj.getX(), y: obj.getY(), width: obj.getWidth, height: obj.getHeight(), solid: obj.isSolid });
        }
    }
})();

Solution 42 - Javascript

You can think like this. Into the <body></body> place a tag <p id='staticVariable'></p> and set its visibility: hide.

Of course you can manage the text inside the previous tag by using jquery. Pratically this tag become your static variable.

Solution 43 - Javascript

{
   var statvar = 0;
   function f_counter()
   {
      var nonstatvar = 0;
      nonstatvar ++;
      statvar ++;
      return statvar + " , " + nonstatvar;
   }
}
alert(f_counter());
alert(f_counter());
alert(f_counter());
alert(f_counter());

This is just another way of having a static variable that I learned somewhere.

Solution 44 - Javascript

I remember JavaScript Closures when I See this.. Here is how i do it..

        function Increment() {
            var num = 0; // Here num is a private static variable
            return function () {
                return ++num;
            }
        }

        var inc = new Increment();
        console.log(inc());//Prints 1
        console.log(inc());//Prints 2
        console.log(inc());//Prints 3

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRajatView Question on Stackoverflow
Solution 1 - JavascriptChristian C. SalvadóView Answer on Stackoverflow
Solution 2 - JavascriptPascal MARTINView Answer on Stackoverflow
Solution 3 - JavascriptkhoomeisterView Answer on Stackoverflow
Solution 4 - JavascriptMattView Answer on Stackoverflow
Solution 5 - JavascriptgpilotinoView Answer on Stackoverflow
Solution 6 - JavascriptMax HeiberView Answer on Stackoverflow
Solution 7 - Javascriptjim_zike_huangView Answer on Stackoverflow
Solution 8 - JavascriptNateView Answer on Stackoverflow
Solution 9 - JavascriptAutomaticoView Answer on Stackoverflow
Solution 10 - JavascriptCOilView Answer on Stackoverflow
Solution 11 - JavascriptHemantView Answer on Stackoverflow
Solution 12 - JavascriptfunrollView Answer on Stackoverflow
Solution 13 - JavascriptDimitris Fasarakis HilliardView Answer on Stackoverflow
Solution 14 - JavascriptSнаđошƒаӽView Answer on Stackoverflow
Solution 15 - JavascriptGetFreeView Answer on Stackoverflow
Solution 16 - JavascriptJoolzCheatView Answer on Stackoverflow
Solution 17 - JavascriptAndrew HareView Answer on Stackoverflow
Solution 18 - JavascriptGreg EView Answer on Stackoverflow
Solution 19 - JavascriptLuca ReghellinView Answer on Stackoverflow
Solution 20 - Javascriptj D3VView Answer on Stackoverflow
Solution 21 - JavascriptKerimView Answer on Stackoverflow
Solution 22 - JavascriptYashView Answer on Stackoverflow
Solution 23 - Javascriptvkarpov15View Answer on Stackoverflow
Solution 24 - JavascriptBostoneView Answer on Stackoverflow
Solution 25 - JavascriptTodd LView Answer on Stackoverflow
Solution 26 - JavascriptcharlieView Answer on Stackoverflow
Solution 27 - JavascriptlindsaymacveanView Answer on Stackoverflow
Solution 28 - Javascriptdanielson317View Answer on Stackoverflow
Solution 29 - JavascriptSatyapriya MishraView Answer on Stackoverflow
Solution 30 - JavascriptMartin WantkeView Answer on Stackoverflow
Solution 31 - JavascripthimanshuView Answer on Stackoverflow
Solution 32 - JavascriptprostiView Answer on Stackoverflow
Solution 33 - JavascriptkofifusView Answer on Stackoverflow
Solution 34 - JavascriptWillem van der VeenView Answer on Stackoverflow
Solution 35 - JavascriptUserView Answer on Stackoverflow
Solution 36 - JavascriptEliuXView Answer on Stackoverflow
Solution 37 - Javascriptrealmag777View Answer on Stackoverflow
Solution 38 - Javascriptvkarpov15View Answer on Stackoverflow
Solution 39 - JavascriptMr. DogeView Answer on Stackoverflow
Solution 40 - JavascriptGerardoView Answer on Stackoverflow
Solution 41 - JavascriptImagine BreakerView Answer on Stackoverflow
Solution 42 - JavascriptCubocicloideView Answer on Stackoverflow
Solution 43 - JavascriptParthiban NagarajanView Answer on Stackoverflow
Solution 44 - JavascriptUthaiahView Answer on Stackoverflow