Is there any way to make “private” variables (those defined in the constructor), available to prototype-defined methods?
TestClass = function(){
var privateField = "hello";
this.nonProtoHello = function(){alert(privateField)};
};
TestClass.prototype.prototypeHello = function(){alert(privateField)};
This works:
t.nonProtoHello()
But this doesn’t:
t.prototypeHello()
I’m used to defining my methods inside the constructor, but am moving away from that for a couple reasons.
@Kai
That won't work. If you do
then
t2.prototypeHello
will be accessing t's private section.@AnglesCrimes
The sample code works fine, but it actually creates a "static" private member shared by all instances. It may not be the solution morgancodes looked for.
So far I haven't found an easy and clean way to do this without introducing a private hash and extra cleanup functions. A private member function can be simulated to certain extent:
I have one solution, but I am not sure it is without flaws.
For it to work, you have to use the following structure:
Here is the code:
How this works is that it provides an instance function "this.getPrivateFields" to access the "privateFields" private variables object, but this function will only return the "privateFields" object inside the main closure defined (also prototype functions using "this.getPrivateFields" need to be defined inside this closure).
A hash produced during runtime and difficult to be guessed is used as parameters to make sure that even if "getPrivateFields" is called outside the scope of closure will not return the "privateFields" object.
The drawback is that we can not extend TestClass with more prototype functions outside the closure.
Here is some test code:
EDIT: Using this method, it is also possible to "define" private functions.
I faced the exact same question today and after elaborating on Scott Rippey first-class response, I came up with a very simple solution (IMHO) that is both compatible with ES5 and efficient, it also is name clash safe (using _private seems unsafe).
Tested with ringojs and nodejs. I'm eager to read your opinion.
You can also try to add method not directly on prototype, but on constructor function like this:
Can't you put the variables in a higher scope?
Try it!