Private fields: using prototype, reducing boilerplate (1)
by mbread
JavaScript
//***********************************
// Re-usable code
//***********************************
var PRIVATES = (function () {
var privateAccess = null;
var module = {};
// A function to be called form a constructor to create the storage for private fields in an object
var prepareObject = function(object) {
var privateStorage = {};
object.loadPrivateAccess = function () {
privateAccess = privateStorage;
}
}
// A function to create a getter/setter function that stores its value in a private field
module.createGetterSetter = function(proto, propertyName) {
proto[propertyName] = function () {
if(typeof this.loadPrivateAccess != "function") prepareObject(this);
this.loadPrivateAccess();
try {
switch (arguments.length) {
case 0:
return privateAccess[propertyName];
case 1:
privateAccess[propertyName] = arguments[0];
break;
}
} finally {
// Obviously this won't work for reentrant calls, but we're in control of the contents of the getter/setter anyway, so we know it's not reentrant
privateAccess = null;
}
};
}
return module;
}());
//***********************************
// Each class (much less boilerplate)
//***********************************
var Class1 = (function () {
var Class1 = function () {
// Construct object
};
PRIVATES.createGetterSetter(Class1.prototype, "myField");
return Class1;
}());
//***********************************
// Tests
//***********************************
function assertEquals(msg, expected, actual) {
if (expected == actual) {
console.debug("Passed: " + expected + " == " + actual);
} else {
console.error("Failed: " + msg + " Expected: " + expected + " Actual: " +...