Javascript unknown number of arguments

in my project, I register different functions (having different number of arguments) as listeners to a number of events. When the event takes place, I need to fire the associated function. I receive the parameters to be passed to listener method in the form of an array whereas the listener function expect each separate argument. So, I am doing it like this but I do not like the approach and would like to know if there is an elegant way of doing it,

function callListenerWithArgs(func, args){
        switch(args.length){
            case 1:
                func(args[0]);
                break;
            case 2:
                func(args[0], args[1]);
                break;
            case 3:
                func(args[0], args[1], args[2]);
                break;
            case 4:
                func(args[0], args[1], args[2], args[3]);
                break;
            default:
                func();
        }
    }

Answers


Use .apply

func.apply(null, args)

If you need to bind to a specific scope, you can pass another argument in to use as this inside the function:

func.apply(scope, args);

Also, a nuance of JavaScript is that you can call functions with undefined values. So making a small tweak to your existing code will work in 95% of all cases (this isn't suggested as a solution, just pointing it out):

// will handle any number of args up to 7
function callListenerWithArgs(func, args){
    func(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
}

If your func is defined as:

function foo(a, b, c){
}

you get a, b, c passed in, along with some more undefined values that get ignored. As I said above, this works in 95% of cases. It doesn't work if you ever check arguments.length in the called function since it will always be the same, regardless of the number of parameters the function defines.


Try this using function.apply

function callListenerWithArgs(func, args){
    func.apply(window, args);
}

functionName.apply(thisScope, arguments) would be more elegant. The arguments argument must be an array.

You can build the Array like:

var args = [];

switch (arguments.length - 1) {
    case 0:
        break;
    case 1:
        args.push(arguments[1]);
        break;
    case 2:
        args.push(arguments[1], arguments[2]);
        break;
    case 3:
        args.push(arguments[1], arguments[2], arguments[3]);
        break;
    default:
        args = Array.prototype.slice.call(arguments, 1);
}

or if the array is already built, just pass it as the second argument to .apply


func.apply(this, args);

See here.


You can get the number of arguments of a function:

var f = function ( ) { console.log(arguments.length); }
f( 2, 3 )  // > 2

That lets you implement your func function directly in place.

function func() {
  var nbArgs = arguments.length;
  // ...
}

Need Your Help

ajax with Spring

java ajax spring jquery

Help me to write spring web application to read from a file and display as a html page

Most reliable way to clean List<T> depending on Predicate<T>

c# linq list predicate

I have List&lt;T&gt; data and Predicate&lt;T&gt; condition.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.