Reputation: 1767
I need constructor that initialize some Objects
with unique name
. I write some code like this:
Obj.prototype.idCounter = 0;
Obj = function() {
this.name = "Obj_" + Obj.prototype.idCounter;
Obj.prototype.idCounter++;
}
var o1 = new Obj();
var o2 = new Obj();
alert(o1.name); // Obj_0
alert(o2.name); // Obj_1
But Obj.prototype.idCounter
is non-private. I know how to create private variable, but I have no idea how to make private static variable.
Upvotes: 1
Views: 71
Reputation: 413702
What you can do is this:
var Obj = function() {
var idCounter = 0;
function Obj() {
this.name = "Obj_" + idCounter;
idCounter++;
}
return Obj;
}();
Now idCounter
is a local variable to that anonymous function, so nothing else can see it except for the constructor function.
Note that you can also do some initialization of the prototype object in there too:
var Obj = function() {
var idCounter = 0;
function Obj() {
this.name = "Obj_" + idCounter;
idCounter++;
}
// one way to add a prototype property, and not
// the simplest
Object.defineProperties(Obj.prototype, {
getInstanceCount: {
value: function() {
return idCounter;
}
}
});
return Obj;
}();
Now when you have an instance of Obj you can call getInstanceCount()
to get a total number of objects created (which would be a weird way to design an API but it's just to illustrate that the prototype functions may get access to those private variables too).
Upvotes: 3
Reputation: 29906
In JavaScript, you usually prefix field names with an underscore _
to indicate they are private. Of course this does not make them really private, but developers should show some self-discipline and consider it as private.
function Obj() {
this.name = "Obj_" + (Obj._idCounter++);
}
Obj._idCounter = 0;
var o1 = new Obj();
var o2 = new Obj();
log(o1.name); // Obj_0
log(o2.name); // Obj_1
function log(x) { var p = document.createElement('pre'); p.appendChild(document.createTextNode(x)); document.body.appendChild(p); }
If you really want to hide something you can of course use closures, as others stated. However that is a bit harder to debug and for some reason that is a bit slower.
Upvotes: 0
Reputation: 10849
There is no way (as far as I know) to replicate private static members the way you described it.
What you could do to solve the problem of keeping your id generator safe is to use the module pattern, and use a sort of privileged access to it from within the module scope.
// using an immediately invoked function to generate the isolated scope
var Obj = (function () {
var idCounter = 0;
return function Obj() {
this.name = "Obj_" + idCounter;
idCounter++;
};
}());
var o1 = new Obj();
var o2 = new Obj();
alert(o1.name); // Obj_0
alert(o2.name); // Obj_1
Upvotes: 3