问题
The intention is to build a wrapper to provide a consistent method of calling native functions with variable arity on various script hosts - so that the script could be executed in a browser as well as in the Windows Script Host or other script engines.
I am aware of 3 methods of which each one has its own drawbacks.
eval()
method:function wrapper () { var str = ''; for (var i=0; i<arguments.lenght; i++) str += (str ?', ':'') + ',arguments['+i+']'; return eval('[native_function] ('+str+')'); }
switch()
method:function wrapper () { switch (arguments.lenght) { case 0: return [native_function] (arguments[0]); break; case 1: return [native_function] (arguments[0], arguments[1]); break; ... case n: return [native_function] (arguments[0], arguments[1], ... arguments[n]); } }
apply()
method:function wrapper () { return [native_function].apply([native_function_namespace], arguments); }
What's wrong with them you ask?
Well, shall we delve into all the reasons why
eval()
is evil? And also all the string concatenation... Not a solution to be labeled "elegant".One can never know the maximum
n
and thus how manycases
to prepare. This also would strech the script to immense proportions and sin against the holy DRY principle.The script could get executed on older (pre- JavaScript 1.3 / ECMA-262-3) engines that don't support the
apply()
method.
Now the question part: is there any another solution out there?
回答1:
Just use apply()
. And for your antiquated execution engines, just do this
if ( 'undefined' == typeof Function.prototype.apply )
{
Function.prototype.apply = function( context, args )
{
// whatever hacky way you want to implement it - i guess eval.
}
}
回答2:
Just like the automatic 'this' variable, there is an 'arguments' variable that holds all the arguments passed in to the function. See javascript variadic.
来源:https://stackoverflow.com/questions/2472702/how-to-create-a-variadic-with-variable-length-argument-list-function-wrapper-i