Class Variables In Javascript
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"