Skip to content

Instantly share code, notes, and snippets.

@bga
Created January 14, 2011 06:12
Show Gist options
  • Save bga/779254 to your computer and use it in GitHub Desktop.
Save bga/779254 to your computer and use it in GitHub Desktop.
/*
Shows that strongly typed vars is possible in js! And do not worry about speed. :) Robust type system is more important than yet another benchmark :P. And i'll plan to make deploy system which checks all types and removes all 'ugly' `with`. This code definitely should be complexer, but i keep it simple.
P.S. `with` rulezzz
P.P.S. As you see its too easy to make field of class strongly typed too.
*/
(function($G){
if(Object.defineProperty && !{}.__defineGetter__)
{
Object.prototype.__defineGetter__ = function(name, _fn)
{
Object.defineProperty(this, name, {get: _fn});
}
};
if(Object.defineProperty && !{}.__defineSetter__)
{
Object.prototype.__defineSetter__ = function(name, _fn)
{
Object.defineProperty(this, name, {set: _fn});
}
};
var _typedVarWithImplictCast = function(varMap, name, Type)
{
var v;
varMap.__defineGetter__(name, function(){ return v });
varMap.__defineSetter__(name, function(nv){ v = Type(nv) }); // throws CastError if cast is impossible
};
var _typedVars = function(varMap)
{
if(varMap == null)
varMap = {};
if(varMap._defTypedVar == null)
{
var varNameToType = {};
varMap._defTypedVar = function(name, Type, v)
{
if(varMap.hasOwnProperty(name))
{
if(varNameToType[name] !== Type)
throw TypeError('redeclaration with different type');
varMap[name] = v;
}
else
{
_typedVarWithImplictCast(varMap, name, Type);
varNameToType[name] = Type;
varMap[name] = v;
}
}
}
return varMap;
};
// export
$G._typedVars = _typedVars;
})(this);
// example
(function($G)
{
_typedVars($G);
_defTypedVar('foo', String, '123');
foo = 234;
console.log(foo + 2);
(function(){with(_typedVars())
{
_defTypedVar('bar', Boolean, false);
bar = 1;
console.log(bar);
}})();
})(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment