views:

104

answers:

2

How do I write a Javascript function that accepts a variable number of parameters, and forwards all of those parameters to other anonymous functions?

For example, consider the scenario of a method that fires an event:

function fireStartedEvent(a,b,c,d,e,f,g,...) {
    for(var i = 0; i < startedListeners.length; i++) {
        startedListeners[i](a,b,c,d,e,f,g,...);
    }
}

Especially since I have an event factory that generates these fire methods, these methods have no interest in knowing how many parameters a given event or its handlers consume. So I have it hard-wired at 7 right now (a through g). If it's any less, no problem. If it's any more, they get cut off. How can I just capture and pass on all parameters?

Thanks.

(Using jQuery or any other Javascript framework is not an option here.)

+5  A: 

This link explains it all.

It covers the use of 'arguments' and 'apply' giving several examples as well as showing other features of the Javascript language.

pst
doesn't seem to apply to what the asker wants.
thephpdeveloper
I think this is *exactly* what the asker wants.
bcat
Thanks, pst. The doc you link to is excellent. I was torn between marking yours or Lauri's answer as the accepted answer because he took the time to apply it to my original question. It was a coin toss. I hope you understand.
Andrew Arnott
@Andrew It's okay, I'm not that involved ;-) However, note that the sample code provided by Lauri is not correct. It may work in some browsers but it is flawed.
pst
Lauri gave you the fish, but I think pst taught you how to use the fishing rod
David Caunt
Ah, I hate browser-specific behavior. I switched to calling apply with args defined as `var args = Array.prototype.slice.call(arguments);` and it still works, presumably in more browsers. Thanks for the extra tip, pst.
Andrew Arnott
+1 I stand corrected on the eval() version.
dirkgently
+5  A: 

I think "apply" and "arguments" are two JavaScript concepts you can use here:

function fireStartedEvent() {
  for (var i = 0; i < startedListeners.length; i++) {
    startedListeners[i].apply(startedListeners[i], arguments);
  }
}

Here's some code from my Firebug console I tried this out with:

a = function(foo) { alert('a: ' + foo); };
b = function(foo, bar) { alert('b: ' + foo + ', ' + bar); };

startedListeners = [a, b];

function fireStartedEvent() {
  for (var i = 0; i < startedListeners.length; i++) {
    startedListeners[i].apply(startedListeners[i], arguments);
  }
}


fireStartedEvent('one', 'two');
Lauri Lehtinen
This code is not correct. arguments is array-like. It is not "an array". apply takes an array as the 2nd parameter.
pst
pst, it seems to work for me, in that the method invoked using apply(null, arguments) gets called and seems to recognize all the distinct arguments. Is there a problem I'm missing?
Andrew Arnott
@pst - I did not know this - do you happen to have an example where the function I posted does not work?
Lauri Lehtinen
@Lauri Arg. You challenged my assertion (and won; it works in Safari, Chrome, FF and IE6-8): I can not find a counter-example. Changed to an upvote. Thanks.
pst