813

How can I create static variables in Javascript?

Matt
  • 25,467
  • 18
  • 120
  • 187
Rajat
  • 32,970
  • 17
  • 67
  • 87
  • we can define label or other html tag with "dispaly:none" style attribute and set variable value for this value and operation on this value. Let's not take hard. – asghar Feb 28 '19 at 19:50
  • The simplest solution I found: don't define a static variable in the class at all. When you want to use a static variable, just define it there and then, e.g. `someFunc = () => { MyClass.myStaticVariable = 1; }`. Then just create a static method to return the static member, e.g. `static getStatic() { return MyClass.myStaticVariable; }`. Then you can just call `MyClass.getStatic()` from outside the class to get hold of the static data ! –  Feb 27 '20 at 12:05
  • I create my own static variable, by adding new attribute to HTML element , `btn.setAttribute( 'arr' , 0 )` I can get/change that value on anywhere on the script `btn.getAttribute('arr') ` – Salem May 25 '22 at 15:53

43 Answers43

953

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"
Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
  • 6
    Presumably `privilegedMethod` is not equivalent to a private method in OO because it seems like it could be called on an instance of MyClass? Do you mean it's privileged because it can access `privateVariable`? – Dónal Nov 11 '11 at 16:41
  • Yes, that's the idea of _privileged_, as intended when explained originally in this [Crockford article](http://www.crockford.com/javascript/private.html) – superjos Sep 26 '12 at 13:41
  • Is Global and Static are the same? Therefore, it is always static in reference when declaring either a variable or function in Javascript? – David Dimalanta Jan 21 '14 at 07:03
  • 3
    Can't `this.constructor` be used to access the static variables from "instance methods"? If yes, it's worth adding it to the answer. – Ciro Santilli OurBigBook.com Jun 22 '14 at 11:33
  • How would you access such a static variable from inside the class, e.g. it's constructor? I use `namespace.MyClass.staticProperty` in the constructor but I think it's kind of bad to hardwire the namespace. – ckuepker Aug 02 '14 at 13:11
  • @ckuepker It depend on how you implement namespacing. If you implement it as a property to an object, eg. `var ns = ns || {}; ns.MyClass = function()...` Then the class has to know its namespace. – dotnetCarpenter Sep 05 '14 at 11:39
  • 2
    You could also mention **static functions** in your example. – David Rodrigues Nov 15 '14 at 15:34
  • 23
    hi, I am not sure I agree with this line // Static variable shared by all instance 'MyClass.staticProperty = "baz";' as to _me_ that infers that you can find baz from 'myInstance.staticProperty' which of course you can't. – fullstacklife Mar 19 '15 at 20:07
  • 5
    Perhaps it should read `MyClass.prototype.staticProperty = "baz";` or to be even more correct to OO principles the static property should actually be defined as an anonymous function `MyClass.prototype.staticProperty = function () {return staticVar;}` and so that all instances access a single variable which could also be altered with a setter. – lindsaymacvean Nov 10 '15 at 12:03
  • 1
    MyClass.staticProperty = "baz"; is not the right way. Any static variable should be using prototype. Are you sure, this is working? – Ananthaprakash May 12 '16 at 17:29
  • 1
    Thought this example can help others, [JSFiddle link](https://jsfiddle.net/suman_jsfiddle/vhkzaya2/) – BeingSuman Dec 17 '16 at 16:45
  • @Dónal - PrivilegedMethod is a closure here. – Deepak Pathak Jan 20 '17 at 06:52
  • This example solution of "MyClass.staticProperty = "baz"" isn't a static variable, its a "class variable" as opposed to an "instance variable". When I hear "static variable" I think the keyword "static" which is a variable that is within a scope, but that is not initialized nor released after going out of scope/ coming into scope. Maybe the original question is asking about class variables; consequence of term overloading. – Minok May 05 '17 at 22:51
  • Does convention dictate that it should be all caps (ie: `MyClass.STATIC_PROPERTY`)? – theyuv Oct 26 '18 at 12:57
  • @theyuv I don't think it does. The all caps convention is fairly strongly tied something being a *constant*, not whether it's a static or class attribute or such. That's not to say some people won't apply all caps to distinguish such things clearly, but I don't think that's widespread enough to override the "ALLCAPS == constant" convention. – Peter Hansen Feb 02 '20 at 22:39
  • What about static variables within a function? That is, a variable that is local to a function but is kept across calls to that function. In other languages: `function someFunction() { static var myStaticVar=0; myStaticVar+=1; console.log(myStaticVar); }`. so that calling it several times would output 1, then 2, then 3 etc. – matteo Jan 01 '21 at 15:54
  • Thanks for the good ES6 update. It was exactly what I was looking for. To see it in context with the earlier option is a bonus. – Anne Gunn Jun 16 '21 at 12:27
598

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.

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.

Goozak
  • 508
  • 1
  • 5
  • 21
Pascal MARTIN
  • 395,085
  • 80
  • 655
  • 663
  • 63
    as a shortcut, you could just do `countMyself.counter = countMyself.counter || initial_value;` if the static variable is never going to be falsey (false, 0, null, or empty string) – Kip Sep 23 '11 at 17:25
  • 3
    Slightly shorter and clearer: (function() { var id = 0; function uniqueID() { return id++; }; })(); – Tom Robinson Sep 21 '13 at 22:13
  • 3
    Counter in closure is very faster than in the class in Firefox. http://jsperf.com/static-counter-in-class-vs-in-closure – Sony Santos Dec 09 '14 at 11:19
  • Use `===` for `typeof` checks else you'll get some weird coercion going on. – dewd May 30 '15 at 08:49
  • @SonySantos Your test shows the opposite for Firefox 40 – bartolo-otrit Sep 19 '15 at 08:28
  • In Firefox 40 they are the same speed, but the closured version is twice as fast in Chrome 47. – Yay295 Jan 08 '16 at 20:41
  • 1
    `if (!('counter' in countMyself)) { ... }` seems less verbose and more semantically correct. Not that most people would do this, but your version of the `if` statement would fail to detect that `countMyself.counter` existed if it was explicitly defined as `undefined`, e.g. `countMyself.counter = undefined` would result in `!('counter' in countMyself) === false` vs. `(typeof countMyself.counter == 'undefined') === true` – Patrick Roberts Jan 10 '18 at 05:46
  • @SonySantos Closures are 75% than doing it in classes in Chrome 75. Thanks for testing! – firetiger77 Jul 18 '19 at 00:02
  • 1
    For the function version at top, instead of `countMyself.counter` isn't `this.counter` better so you don't hardcode the function name. – SO Stinks Feb 29 '20 at 07:03
  • I don't want that if check to run every time; why don't you have the function rewrite itself with a non-checking version, on its first run? – einpoklum Jul 01 '22 at 20:51
120

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
Chris
  • 4,594
  • 4
  • 29
  • 39
  • 27
    I'd say this is the most idiomatic way to do it in JavaScript. Too bad it doesn't get too many upvotes thanks to other methods which are probably more palatable to people that come from other languages. –  Jun 02 '14 at 11:42
  • 1
    I'd rephrase using 'closure' rather than just 'IIFE'. – zendka Sep 03 '19 at 18:44
  • Congrats, definitively the best reply, simple is beautiful. Even if it is obvious, may I extend the response:`var incr = (function (delta) { var i = 1; return function (delta) return i+=delta;} })();` – Bruno L. Jun 18 '20 at 18:19
  • 2
    I have heard them called Anonymous Self-Invoking Functions, otherwise known as "ASIF's" ("as if" you could actually read them.) :) – blackcatweb Jul 01 '21 at 02:52
45

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.

Matt
  • 25,467
  • 18
  • 120
  • 187
41

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);
}
gpilotino
  • 13,055
  • 9
  • 48
  • 61
  • 3
    As far as I can understand, this method has one (only one?) advantage over pascal MARTIN's way: you can use it on anonymous functions. An example of this would be great – Dan Oct 10 '11 at 10:36
  • 30
    `arguments.callee` is deprecated. – Quolonel Questions Oct 09 '13 at 06:31
  • I pretty much ridicule JS all the time, but `callee` seemed a nice thing to have. I wonder why the hack did they decide to deprecate this... :| – user2173353 Dec 21 '16 at 10:26
31

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.

Max Heiber
  • 14,346
  • 12
  • 59
  • 97
  • `Foo.bar;` returns the function assigned to it, not the string returned by the function as your comment implies. –  Jun 21 '15 at 19:28
  • Can you add some information on how to set (overwrite) a static value in those both examples? – Wilt Jun 20 '16 at 15:20
  • 1
    @Wilt in both cases, a "static" property is just a property on the function, so you set it and overwrite it just like you would any other property in JavaScript. In both cases, you can set the `bar` property of `Foo` to `3` like this: `Foo.bar = 3;` – Max Heiber Jun 22 '16 at 01:57
  • ES6 specific question: https://stackoverflow.com/questions/28445693/how-do-i-make-a-public-static-field-in-an-es6-class – Ciro Santilli OurBigBook.com Aug 04 '19 at 19:54
28
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();
jim_zike_huang
  • 281
  • 3
  • 2
16

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.

Benoit Garret
  • 14,027
  • 4
  • 59
  • 64
Nate
  • 804
  • 8
  • 6
  • looks constructor + prototype (hybrid) – Ganesh Kumar Jan 25 '12 at 00:49
  • 2
    This places the Person object in the global namespace. Not a solution i would recommend. – Ghola Mar 18 '13 at 00:12
  • I dont think this is a true static variable because it is instantiated differently with each new object. A static object should be consistent across all objects inheriting from the parent prototype? – lindsaymacvean Nov 10 '15 at 12:48
  • 1
    @Ghola The intention here was to explain how to create a static variable. Proper namespacing and avoiding globals is a separate topic which may have added to the complexity of the answer. It's up to the user to determine how to attach the constructor without polluting. If it's good enough for Nicholas Zakas, it's good enough for me. – Nate Mar 18 '16 at 02:47
  • @lindsaymacvean It's a static variable because the single value is shared across all instances. It's OK for the value to change. If one instance changes the value, all instances will be affected. It's not likely it would be used exactly the same as the example above. Allowing the value to be set during instantiation is just to show it's possible. A more likely use case would be to only have the getter and setter or at least check to make sure it's being set to something other than undefined. – Nate Mar 18 '16 at 02:56
15

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.

Automatico
  • 12,420
  • 9
  • 82
  • 110
9

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
COil
  • 7,201
  • 2
  • 50
  • 98
8

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;
Hemant
  • 4,537
  • 8
  • 41
  • 43
8

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

Method 4 for strict mode

'use strict'
{
    let staticVar = 0 ;
    var someFunc4 = function(){
        alert(++staticVar) ;
    } ;
}

someFunc4() ; //prints 1
someFunc4() ; //prints 2
someFunc4() ; //prints 3
GetFree
  • 40,278
  • 18
  • 77
  • 104
8

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).
JΛYDΞV
  • 8,532
  • 3
  • 51
  • 77
  • Okay, but to be clear this explicitly adds static *class* features right? I followed the links and "static variables" are not mentioned. They list static public fields, private methods and private fields. None of which are the same as static variables. So the older answers here are still valid? – Heath Raftery Sep 26 '21 at 04:26
  • @HeathRaftery No, your right, I see what I did. I should have typed _"static fields"_, or even _"static class-members"_, and I wrote _"static-variables"_. You could of edited it, I mean like you didn't have to, but you would have been right if you did. – JΛYDΞV Sep 26 '21 at 05:28
7

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.

Andrew Hare
  • 344,730
  • 71
  • 640
  • 635
  • this one helped me to upload multiple files..... var foo = {counter:1}; function moreFiles() { fileName = "File" + foo.counter; foo.counter = foo.counter + 1; – veer7 Jun 26 '12 at 10:22
7

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;
  };
})();
funroll
  • 35,925
  • 7
  • 54
  • 59
7

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.

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
6

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
Sнаđошƒаӽ
  • 16,753
  • 12
  • 73
  • 90
5

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
});
JoolzCheat
  • 261
  • 4
  • 8
4

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).

Neeraj Kumar
  • 771
  • 2
  • 16
  • 37
Greg E
  • 53
  • 5
4

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);
Luca Reghellin
  • 7,426
  • 12
  • 73
  • 118
2

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

Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
Kerim Tim.
  • 1,159
  • 12
  • 13
1

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.

Yash
  • 9,250
  • 2
  • 69
  • 74
1

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.

vkarpov15
  • 3,614
  • 24
  • 21
0

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

Bostone
  • 36,858
  • 39
  • 167
  • 227
0

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);
Todd L
  • 91
  • 1
  • 3
0

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!!

charlie
  • 41
  • 5
0

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.

lindsaymacvean
  • 4,419
  • 2
  • 19
  • 21
0

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.

danielson317
  • 3,121
  • 3
  • 28
  • 43
0

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
drneel
  • 2,887
  • 5
  • 30
  • 48
0

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
Martin Wantke
  • 4,287
  • 33
  • 21
  • This is not a valid solution: the `_privateStatic` is actually created as a global object (i.e. as member of `window` when used in a browser). So while it is static, it is not private and does not belong to `Class`. – Bart Nov 15 '16 at 15:03
0

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.
himanshu
  • 53
  • 1
  • 4
0

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.

prosti
  • 42,291
  • 14
  • 186
  • 151
0

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.

kofifus
  • 17,260
  • 17
  • 99
  • 173
0

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);
Willem van der Veen
  • 33,665
  • 16
  • 190
  • 155
0

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"
  }
}
EliuX
  • 11,389
  • 6
  • 45
  • 40
0

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
    }

}
realmag777
  • 2,050
  • 1
  • 24
  • 22
0

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
vkarpov15
  • 3,614
  • 24
  • 21
0

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)
  }
}
Mr. Doge
  • 796
  • 5
  • 11
-1

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
Gerardo
  • 1,928
  • 4
  • 24
  • 34
  • This method works, but you are poluting the `Function.prototype` – Dan Oct 10 '11 at 21:21
  • @Dan: It is my understanding this would just be for circle and not Function. At least that's what Chrome tries to tell me: `function circle() {}` | `circle.prototype` | `circle.prototype.pi = 3.14` | `circle.prototype` | `Function.prototype` | `Function.__proto__` (if that is what you meant) – Aktau Jan 21 '13 at 12:10
-1

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.

Thomas Ayoub
  • 29,063
  • 15
  • 95
  • 142
-1

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!

User
  • 71
  • 1
  • 7
-2
{
   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.

  • 7
    The outer pair of `{}` do not do anything; JavaScript is not block scoped, it is function scoped. Because of that you are declaring `statvar` as a global. If instead of a `{` and `}` you wrapped it with a self-invoking anonymous function `(function () {` and `}());` It would be closer to what you think is happening there. – Useless Code Mar 29 '13 at 11:32
  • It is not clear what you are trying to show us here - and how it is related to the question. Please try to be more descriptive, and improve your answer. – Matt May 05 '14 at 09:15
-3

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
Uthaiah
  • 1,283
  • 13
  • 14