javascript - How to write a JS function that accepts and "forwards" variable number of parameters? - Stack Ove

How do I write a Javascript function that accepts a variable number of parameters, and forwards all of

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.)

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.)

Share Improve this question edited Oct 25, 2009 at 3:20 bcat 8,9413 gold badges36 silver badges42 bronze badges asked Oct 25, 2009 at 2:52 Andrew ArnottAndrew Arnott 81.9k28 gold badges139 silver badges180 bronze badges 1
  • Is it possible to pass parameters as an array in JavaScript? That could do it. – Cyclone Commented Oct 25, 2009 at 2:53
Add a ment  | 

2 Answers 2

Reset to default 8

Solving this requires knowledge of two JavaScript concepts.

The first is the special arguments local variable that can be used to access the function arguments without knowing their name and it works like an Array. However, arguments is not an Array, but is "array like" -- having properties named 0..n-1, where n is the number of arguments to the function and a length property -- object. A simple demonstration usage might be:

function f (a) { // can include names still, if desired
    // arguments instanceof Array -> false (exceptions to this?)
    var firstArg = arguments[0]
    // a === firstArg -> always true
    // iterate all arguments, just as if it were an Array:
    for (var i = 0; i < arguments.length; i++) {
        alert(i + " : " + arguments[i])
    }
}
f("a","b","c")

The second feature is Function.apply which will invoke a function with a specific context (this when it is called) with arguments that result from the expansion of an "array like" object. But see 1.

Thus, putting it together:

function fireStartedEvent() {
    for(var i = 0; i < startedListeners.length; i++) {
        // jQuery will often pass in "cute" things, such as a element clicked
        // as the context. here we just pass through the current context, `this`,
        // as well as the arguments we received.
        var arg = Array.prototype.slice.call(arguments)
        startedListeners[i].apply(this, args)
    }
}

1 While the ECMAScript specification only calls for an "array like" object, Function.apply does not universally work with an "array like" object and a number of mon implementations require a proper Array object. The warning from the Function.apply link:

Note: Most browsers, including Chrome 14 and Internet Explorer 9, still do not accept array like objects and will throw an exception [if a non-Array object is passed]. [FireFox was fixed in version 4.]

Thankfully, there is a relatively simply idiom to turn an "array like" object into an Array (which is ironic because Array.slice does universally work with an "array like" object):

var args = Array.prototype.slice.call(arguments);

(And then args can be universally used in be used in Function.apply.)

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');

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744236379a4564490.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信