Created
January 14, 2011 06:12
-
-
Save bga/779254 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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