Proxy object pattern
by Douglas Enas
JavaScript
// defineClass creates an object constructor.
// options: {
// "constructor": (optional) function to initialize the object
// "public": object containing the public functions
// "private": object containing the private functions, only callable by the object itself
// }
var defineClass = function (options) {
var realClass, // has both public and private functions, and the data
proxyClass, // has just the public functions
constructorFunction,
property,
createProxyFunction,
publicProperties = options["public"] || {}, // "public" is a reserved keyword, so can't use options.public
privateProperties = options["private"] || {}; // same for "private"
// The constructorFunction creates instances of the class we're defining here.
constructorFunction = function () {
// Explicitly return an object, instead of using 'this'.
return new proxyClass(new realClass());
};
// Use the constructor if defined, otherwise create an empty constructor.
realClass = options.constructor || function() { };
// Add the public and private properties to the real class's prototype.
for (property in publicProperties) {
if (publicProperties.hasOwnProperty(property)) {
realClass.prototype[property] = publicProperties[property];
}
}
for (property in privateProperties) {
if (privateProperties.hasOwnProperty(property)) {
realClass.prototype[property] = privateProperties[property];
}
}
// A proxy has a special property referencing the real object it's wrapping.
proxyClass = function (realObject) {
this.__realObject__ = realObject;
};
// Objects created from constructorFunction will be instances of proxyClass.
// So assigning the prototype means instanceof will still make sense.
// e.g. (new MyClass()) instanceof MyClass === true
proxyClass.prototype =...