views:

206

answers:

2

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.

  1. eval() method:

    function wrapper () {
        var str = '';
        for (var i=0; i<arguments.lenght; i++)
            str += (str ?', ':'') + ',arguments['+i+']';
        return eval('[native_function] ('+str+')');
        }
    
  2. 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]);
            }
        }
    
  3. apply() method:

    function wrapper () {
        return [native_function].apply([native_function_namespace], arguments);
        }
    

What's wrong with them you ask?

  1. 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".

  2. One can never know the maximum n and thus how many cases to prepare. This also would strech the script to immense proportions and sin against the holy DRY principle.

  3. 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  A: 

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.
  }
}
Peter Bailey
So, no fourth method? Well then, I'll go with this. Thanks!
U-D13
A: 

How about overloading your methods http://ejohn.org/blog/javascript-method-overloading/ ?

Quickredfox