Is there any way to make “private” variables (those defined in the constructor), available to prototype-defined methods?
TestClass = function(){
var priv
Here's something I've come up with while trying to find most simple solution for this problem, perhaps it could be useful to someone. I'm new to javascript, so there might well be some issues with the code.
// pseudo-class definition scope
(function () {
// this is used to identify 'friend' functions defined within this scope,
// while not being able to forge valid parameter for GetContext()
// to gain 'private' access from outside
var _scope = new (function () { })();
// -----------------------------------------------------------------
// pseudo-class definition
this.Something = function (x) {
// 'private' members are wrapped into context object,
// it can be also created with a function
var _ctx = Object.seal({
// actual private members
Name: null,
Number: null,
Somefunc: function () {
console.log('Something(' + this.Name + ').Somefunc(): number = ' + this.Number);
}
});
// -----------------------------------------------------------------
// function below needs to be defined in every class
// to allow limited access from prototype
this.GetContext = function (scope) {
if (scope !== _scope) throw 'access';
return _ctx;
}
// -----------------------------------------------------------------
{
// initialization code, if any
_ctx.Name = (x !== 'undefined') ? x : 'default';
_ctx.Number = 0;
Object.freeze(this);
}
}
// -----------------------------------------------------------------
// prototype is defined only once
this.Something.prototype = Object.freeze({
// public accessors for 'private' field
get Number() { return this.GetContext(_scope).Number; },
set Number(v) { this.GetContext(_scope).Number = v; },
// public function making use of some private fields
Test: function () {
var _ctx = this.GetContext(_scope);
// access 'private' field
console.log('Something(' + _ctx.Name + ').Test(): ' + _ctx.Number);
// call 'private' func
_ctx.Somefunc();
}
});
// -----------------------------------------------------------------
// wrap is used to hide _scope value and group definitions
}).call(this);
function _A(cond) { if (cond !== true) throw new Error('assert failed'); }
// -----------------------------------------------------------------
function test_smth() {
console.clear();
var smth1 = new Something('first'),
smth2 = new Something('second');
//_A(false);
_A(smth1.Test === smth2.Test);
smth1.Number = 3;
smth2.Number = 5;
console.log('smth1.Number: ' + smth1.Number + ', smth2.Number: ' + smth2.Number);
smth1.Number = 2;
smth2.Number = 6;
smth1.Test();
smth2.Test();
try {
var ctx = smth1.GetContext();
} catch (err) {
console.log('error: ' + err);
}
}
test_smth();