Is there any way to make “private” variables (those defined in the constructor), available to prototype-defined methods?
TestClass = function(){
var priv
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:
var TestClass =
(function () {
// difficult to be guessed.
var hash = Math.round(Math.random() * Math.pow(10, 13) + + new Date());
var TestClass = function () {
var privateFields = {
field1: 1,
field2: 2
};
this.getPrivateFields = function (hashed) {
if(hashed !== hash) {
throw "Cannot access private fields outside of object.";
// or return null;
}
return privateFields;
};
};
TestClass.prototype.prototypeHello = function () {
var privateFields = this.getPrivateFields(hash);
privateFields.field1 = Math.round(Math.random() * 100);
privateFields.field2 = Math.round(Math.random() * 100);
};
TestClass.prototype.logField1 = function () {
var privateFields = this.getPrivateFields(hash);
console.log(privateFields.field1);
};
TestClass.prototype.logField2 = function () {
var privateFields = this.getPrivateFields(hash);
console.log(privateFields.field2);
};
return TestClass;
})();
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:
var t1 = new TestClass();
console.log('Initial t1 field1 is: ');
t1.logField1();
console.log('Initial t1 field2 is: ');
t1.logField2();
t1.prototypeHello();
console.log('t1 field1 is now: ');
t1.logField1();
console.log('t1 field2 is now: ');
t1.logField2();
var t2 = new TestClass();
console.log('Initial t2 field1 is: ');
t2.logField1();
console.log('Initial t2 field2 is: ');
t2.logField2();
t2.prototypeHello();
console.log('t2 field1 is now: ');
t2.logField1();
console.log('t2 field2 is now: ');
t2.logField2();
console.log('t1 field1 stays: ');
t1.logField1();
console.log('t1 field2 stays: ');
t1.logField2();
t1.getPrivateFields(11233);
EDIT: Using this method, it is also possible to "define" private functions.
TestClass.prototype.privateFunction = function (hashed) {
if(hashed !== hash) {
throw "Cannot access private function.";
}
};
TestClass.prototype.prototypeHello = function () {
this.privateFunction(hash);
};