38

In the following code, I would like to have a counter to keep track of the number of Person objects created. This code is not doing so, how would I accomplish that?

function Person(){
    this.name = "Peter";
    this.counter = this.counter + 1;
    alert(this.counter);
}

Person.prototype.counter = 0;

var p1 = new Person;
var p2 = new Person;
JOM
  • 8,139
  • 6
  • 78
  • 111
indianwebdevil
  • 4,879
  • 7
  • 37
  • 51

5 Answers5

75
function Person(){
    this.name = "Peter";
    Person.counter++;
    alert(Person.counter);
}

Person.counter = 0;

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

Make the "static" variable a property of the Person function, rather than the prototype, and use Person instead of this inside the constructor.

This is possible because JavaScript functions are first-class (i.e. they are objects), so can have properties of their own.

Here's a working example of the above code.

James Allardice
  • 164,175
  • 21
  • 332
  • 312
12

You can also make your counter variable "private", declaring it as local to a closure. It's the best way to have something similar to private - static variables:

var Person = (function() {

    var counter = 0;

    return function() {
        counter++;
        this.name = "Peter";
        alert(counter);
    };
})();


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

Example: https://jsfiddle.net/patodiblasi/67wucsqx/

Pato
  • 671
  • 6
  • 17
6

There are no static properties. If you want you can store data on the Person function.

function Person(){
    this.name = "Peter";
    Person.counter++;
    alert(Person.counter);
}
Raynos
  • 166,823
  • 56
  • 351
  • 396
5

For a static you can assign a property to the function object itself;

Person.counter = 0;

And within the constructor increment with;

Person.counter += 1;

You can also check-if-undefined and create Person.counter within the constructor

function Person(){
   if (typeof Person.counter === 'undefined')
      Person.counter = 0;
   else
      Person.counter += 1;
   ...
Alex K.
  • 171,639
  • 30
  • 264
  • 288
1

There is no such thing like static class variables/properties in js. The simplest approach is just use the "class" function as a namespace for static variables.

It means, just access in Person.count directly.

You can use closures as well, but actually in 90% cases it will be overkill. In modern browsers you also can redefine getter/setter function to wrap usage of Person.count and other "static" variables.

This snippet demonstrates the idea:

    function borrow(obj, borrowobj, fname) {
    obj.__defineGetter__(fname, function() {
         return borrowobj[fname]   
    })  

    obj.__defineSetter__(fname, function(val) {
             borrowobj[fname] = val      
    })
}

function Person() {
    borrow(this, Person, "count");
    this.count++
}

Person.count = 0;

new Person();
new Person();
var p = new Person();
alert(p.count);
demisx
  • 7,217
  • 4
  • 45
  • 43
shabunc
  • 23,119
  • 19
  • 77
  • 102