Skip to content

Instantly share code, notes, and snippets.

@bga
Created August 8, 2010 18:24
Show Gist options
  • Save bga/514372 to your computer and use it in GitHub Desktop.
Save bga/514372 to your computer and use it in GitHub Desktop.
/**
@fn call function with <this> = <that> and <arguments> matched from <argMap> by names
@param that {Any} <this> for function call
@param argMap {Object} map argName -> argValue
@example
var _fn = function(a, b, c)
{
console.log('a = ', a, 'b = ', b, 'с = ', c);
};
_fn._jbNamedApply(null, {b: 1}); // a = undefined b = 1 с = undefined
_fn._jbNamedApply(null, {b: 1, a: 0}); // a = 0 b = 1 с = undefined
_fn._jbNamedApply.call(1, 1, {}); // TypeError: first argument must be function
_fn._jbNamedApply(null, 1); // TypeError: 3rd argument must not null
_fn._jbNamedApply(null, {b: 1, a: 0, d: 3}); // SyntaxError: function hasnt argument "d"
var _fn2 = function(){};
_fn2._jbNamedApply(null, {b: 1, a: 0, d: 3}); // SyntaxError: function hasnt named arguments
@return result of function call
*/
Function.prototype._jbNamedApply = function(that, argMap)
{
var _fn = this;
if(typeof(_fn) != 'function')
throw new TypeError('first argument must be function');
if(argMap == null)
throw new TypeError('3rd argument must not null');
var argToPosMap = _fn.jbArgToPosMap_;
if(argToPosMap == null)
{
var fnCode = '' + _fn;
var argString = fnCode.slice(fnCode.indexOf('(') + 1, fnCode.lastIndexOf(')', fnCode.indexOf('{'))). // get arguments string
replace(/\/\*[\s\S]*?\*\//g, ''). // and strip comments
replace(/\/\/[\s\S]*?\n/g, '').
/*#if $jb.Deploy._const('support:String.prototype.trim') */
/*## trim() */
/*#else*/
replace(/^\s+|\s+$/g, '')
/*#endif*/
;
argToPosMap = _fn.jbArgToPosMap_ = {};
if(argString)
{
var argNames = argString.split(/\s*,\s*/);
var i = -1, len = argNames.length; while(++i < len)
argToPosMap[argNames[i]] = i;
}
else
{
_fn.jbHasntArguments_ = true;
}
}
if(_fn.jbHasntArguments_)
{
/*#if $jb.Deploy._const('support:Object.prototype.__count__') */
/*## if(argMap.__count__) throw new SyntaxError('function hasnt named arguments'); */
/*#else*/
for(var name in argMap)
{
if(argMap.hasOwnProperty(name))
throw new SyntaxError('function hasnt named arguments')
}
/*#endif*/
}
else
{
var argValues = [];
for(var name in argMap)
{
if(argMap.hasOwnProperty(name))
{
var pos = argToPosMap[name];
if(pos == null)
throw new SyntaxError('function hasnt argument "' + name + '"')
argValues[pos] = argMap[name];
}
}
return _fn.apply(that, argValues);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment