I created a function which has, I believe, truly private variables. It's not quite production ready for several reasons:
- It's using
Object.defineProperty
-- I can deal with this - It is re-defining every function in the prototype by doing
eval( fn.toString() )
-- I do not like this - I'm re-defining the prototypes, hence doing-away with the advantage of prototypes! -- deal breaker
Anyway, I'm putting this out there for critique / suggestions / recommendations for how to fix the above points. I'm not sure I'll ever really do anything with it, but I find it to be an interesting problem:
function foo(){
this.definePrivateProperties('foo', 'bar');
}
foo.prototype.setFoo = function(x){
this.foo = x;
};
foo.prototype.getFoo = function(){
return this.foo;
};
foo.prototype.definePrivateProperties = function(){
var self = this,
args = arguments,
validFns = {},
proto = this.__proto__;
// replace all functions in prototype with new ones!
// set a random key on each new function
// (not 100% secure, but close enough for now)
// this ensures that the function is unique to -this- object
for(var fn in proto){
this[ fn ] = eval( '(' + proto[fn] + ')' );
validFns[ this[ fn ].key = Math.random() ] = 1;
}
for(var i=0, l=args.length; i<l; i++){
(function(){
var val;
Object.defineProperty(self, args[i], {
get : function getter(){
if(validFns[ arguments.callee.caller.key ])
return val;
},
set : function setter(v){
if(validFns[ arguments.callee.caller.key ])
val = v;
},
configurable : true,
enumerable : false
});
})();
}
};
> var x = new foo();
> x.setFoo(42);
> x.foo = 20;
20
> x.foo;
undefined
> x.getFoo();
42
closure
mechanism for creating truly private JS variables as described here: javascript.crockford.com/private.html. \$\endgroup\$ – jfriend00 Nov 3 '11 at 16:28