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;
1
  • 1
    Can somebody explain how this actually works. Commented Sep 5, 2011 at 11:35

5 Answers 5

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.

Sign up to request clarification or add additional context in comments.

4 Comments

3rd answer, but the most complete/correct.
If I have counter inside Person, then how can I obtain it from it's intance, like p1?
@Dims you can get it from a reference to the constructor: p1.constructor.counter
I'd like to add it's not necessary to use Person.counter, Person.prototype.counter would works too. the point is you cannot use this.counter (or more specifically, set it)
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/

Comments

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);
}

Comments

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

Comments

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.