var def = function(functions, parent) { return function() { var types = []; var args = []; eachArg(arguments, function(i, elem) { args.push(elem); types.push(whatis(elem)); }); if(functions.hasOwnProperty(types.join())) { return functions[types.join()].apply(parent, args); } else { if (typeof functions === 'function') return functions.apply(parent, args); if (functions.hasOwnProperty('default')) return functions['default'].apply(parent, args); } }; }; var eachArg = function(args, fn) { var i = 0; while (args.hasOwnProperty(i)) { if(fn !== undefined) fn(i, args[i]); i++; } return i-1; }; var whatis = function(val) { if(val === undefined) return 'undefined'; if(val === null) return 'null'; var type = typeof val; if(type === 'object') { if(val.hasOwnProperty('length') && val.hasOwnProperty('push')) return 'array'; if(val.hasOwnProperty('getDate') && val.hasOwnProperty('toLocaleTimeString')) return 'date'; if(val.hasOwnProperty('toExponential')) type = 'number'; if(val.hasOwnProperty('substring') && val.hasOwnProperty('length')) return 'string'; } if(type === 'number') { if(val.toString().indexOf('.') > 0) return 'float'; else return 'int'; } return type; }; var out = def({ 'int': function(a) { alert('Here is int '+a); }, 'float': function(a) { alert('Here is float '+a); }, 'string': function(a) { alert('Here is string '+a); }, 'int,string': function(a, b) { alert('Here is an int '+a+' and a string '+b); }, 'default': function(obj) { alert('Here is some other value '+ obj); } }); out('ten'); out(1); out(2, 'robot'); out(2.5); out(true);