Skip to content Skip to sidebar Skip to footer

Class Variables In Javascript

I'm having a bit of trouble trying to get class variables to work in javascript. I thought that I understood the prototype inheritance model, but obviously not. I assumed that

Solution 1:

Static (class level) variables can be done like this:

functionclassA(){
    //initialize
}

classA.prototype.method1 = function(){
    //accessible from anywhere
    classA.static_var = 1;
    //accessible only from THIS objectthis.instance_var = 2;
}

classA.static_var = 1;  //This is the same variable that is accessed in method1()

Your output seems strange because of the way javascript handles prototypes. Calling any method / retreiving a variable of an instantiated object checks the instance first, THEN the prototype. i.e.

var a = newclassA();
classA.prototype.stat = 1;

// checks a.stat which is undefined, then checks classA.prototype.stat which has a valuealert(a.stat); // (a.stat = undefined, a.prototype.stat = 1)// after this a.stat will not check the prototype because it is defined in the object.
a.stat = 5;  // (a.stat = 5, a.prototype.stat = 1)// this is essentially a.stat = a.stat + 1;
a.stat++; // (a.stat = 6, a.prototype.stat = 1) 

Solution 2:

I assumed that since prototypes will be shared between objects then so will their variables.

They are, but this:

a.shared++

is not doing what you think it's doing. It's in fact (approximately) sugar syntax for:

(a.shared= a.shared+1)-1

(the -1 being to return the pre-increment value, not that you're actually using the retrun value, but still.)

So this is actually doing an assigment to a.shared. When you assign to an instance member you are always writing to that instance's own members, not touching any members of any of its prototypes. It's the same as saying:

classA.prototype.shared= 1;a.shared= 2;

So your new a.shared hides the prototype.shared without altering it. Other instances of classA would continue to show the prototype's value 1. If you deleted a.shared you would once again be able to see the prototype's variable that was hidden behind it.

Solution 3:

If you want to have a class variable, something like a static variable in Java, then you can declare a variable in the parent class, but then you shouldn't access it as a variable of the child objects. This article has a nice example of the class Circle having the variable Circle.PI = 3.14 while all the instances of Circle access it as Circle.PI (instead of c.PI).

So my answer is that if you want to have a class variable shared in classA then you shall declare the variable shared in classA, and later you should use classA.shared instead of a.shared. Changing a.shared will never result in classA.shared being changed.

Solution 4:

You just put the member right on the "class" which in JavaScript is the function that constructs objects:

functionClassA(x) { this.x = x; }
ClassA.shared = "";
ClassA.prototype.foo = function() {
    returnClassA.shared + this.x;
}

var inst1 = newClassA("world");
var inst2 = newClassA("mars");

ClassA.shared = "Hello ";
console.log(inst1.foo());
console.log(inst2.foo());
ClassA.shared = "Good bye ";
console.log(inst1.foo());
console.log(inst2.foo());

Solution 5:

Incrementing the shared property via the instance makes it a property of that instance, which is why you're seeing this behaviour.

Once you've done that, you'll never be accessing the prototype for that property through the instance, but its own property.

>>>function ConstructorA() {};>>>ConstructorA.prototype.shared = 0;>>>var a = new ConstructorA();>>>ConstructorA.prototype.shared++;>>>a.shared
1
>>>a.hasOwnProperty("shared")
false
>>>a.shared++;>>>a.hasOwnProperty("shared")
true

This is why the correct solution is to use ConstructorA.shared, as suggested in many of the answers so far, and always access it through the constructor function, not an instance.

It might help to consider that there's no such thing as a class in JavaScript. "Instances" created with the new operator are just objects which have been created by a particular constructor function and have a particular prototype chain. This is why a.shared won't be able to access ConstructorA.shared - property access involves looking at the object in question for the named property, and failing that, walking its prototype chain looking for the property, but the constructor function which created the object isn't part of the prototype chain.

Post a Comment for "Class Variables In Javascript"