JavaScript Object Encapsulation
by andrewdavey
JavaScript
// Helper function to create a proxy object that will pass on calls
// to public functions of the target object.
var createProxy = function (type) {
// Create a new Proxy type for the type
var Proxy = function(target) {
this.target = target;
};
// Add all the public functions to the Proxy.
for (var prop in type.prototype) {
(function(prop) {
if (type.prototype[prop].isPublic) {
Proxy.prototype[prop] = function() {
// Call the original function of the target.
this.target[prop].apply(this.target, arguments);
};
}
}(prop));
}
return Proxy;
};
// Helper function to mark a function as public.
var public = function(f) {
f.isPublic = true;
return f;
};
var Class = function(members) {
var Proxy, constructor;
function Type() {
constructor.apply(this, arguments);
return new Proxy(this);
}
for (var property in members) {
if (property === "constructor") {
constructor = members[property];
} else {
Type.prototype[property] = members[property];
}
}
Proxy = new createProxy(Type);
return Type;
};
var Foo = Class({
constructor: function() {
this.value = 42;
},
// note the "public" marker applied to this function
magic: public(function() {
alert('Reading secret value: ' + this.secret());
}),
// this is a private function
secret: function() {
return this.value;
}
});
var p = new Foo();
p.magic();
if (("secret" in p) === false) {
alert("secret function not publicly visible.");
}
if (("value" in p) === false) {
alert("value property not publicly visible.");
}