Skip to content

Instantly share code, notes, and snippets.

@JamieMason
Created April 4, 2011 14:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JamieMason/901673 to your computer and use it in GitHub Desktop.
Save JamieMason/901673 to your computer and use it in GitHub Desktop.
Encapsulates an object and exposes each of it's properties with their own getter and setter, which maintains the original data type. Methods can be overridden to validate properties more strictly if needed.
var encapsulate = (function()
{
var rGetFirstChar = /^([a-z])/;
function isNumber (value)
{
return !isNaN(parseFloat(value)) && typeof value !== 'string';
}
function curry (fn /*, ... */)
{
var aCurryArgs = Array.prototype.slice.call(arguments, 1);
return function ( /* ... */ )
{
var aCalleeArgs = Array.prototype.slice.call(arguments, 0),
aMergedArgs = aCurryArgs.concat(aCalleeArgs);
return fn.apply(this, aMergedArgs);
};
}
function firstCharToUpperCase (s, char0)
{
return char0.toUpperCase();
}
function getProperty (obj, key)
{
return obj[key];
}
function setProperty (sMethodName, obj, key, value)
{
obj[key] = value;
}
function setBoolean (sMethodName, obj, key, value)
{
if (typeof value !== 'boolean')
{
throw new TypeError([sMethodName, 'allows only Booleans'].join(' '));
}
obj[key] = value;
}
function setNumber (sMethodName, obj, key, value)
{
if (!isNumber(value))
{
throw new TypeError([sMethodName, 'allows only Numbers'].join(' '));
}
obj[key] = value;
}
function setString (sMethodName, obj, key, value)
{
if (typeof value !== 'string')
{
throw new TypeError([sMethodName, 'allows only Strings'].join(' '));
}
obj[key] = value;
}
function encapsulate (oData)
{
var sKeyFirstUp,
sKey,
mValue,
fSetter,
sSetterName,
oInterface = {};
for (sKey in oData)
{
mValue = oData[sKey];
if (typeof mValue === 'function')
{
continue;
}
if (mValue !== null && typeof mValue === 'object' && !('length' in mValue))
{
oInterface[sKey] = encapsulate(mValue);
continue;
}
sKeyFirstUp = sKey.replace(rGetFirstChar, firstCharToUpperCase);
sSetterName = 'set' + sKeyFirstUp;
oInterface['get' + sKeyFirstUp] = curry(getProperty, oData, sKey);
fSetter = typeof mValue === 'string' ? setString : typeof mValue === 'boolean' ? setBoolean : isNumber(mValue) ? setNumber : setProperty;
oInterface[sSetterName] = curry(fSetter, sSetterName, oData, sKey);
}
return oInterface;
}
return encapsulate;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment