276

Is it possible to convert an array in JavaScript into a function argument sequence? Example:

run({ "render": [ 10, 20, 200, 200 ] });

function run(calls) {
  var app = .... // app is retrieved from storage
  for (func in calls) {
    // What should happen in the next line?
    var args = ....(calls[func]);
    app[func](args);  // This is equivalent to app.render(10, 20, 200, 200);
  }
}
2
  • 3
    Check for a similar question also here: stackoverflow.com/questions/2856059/… Commented Feb 25, 2014 at 11:14
  • 4
    I guess it doesn't matter, but it seems odd that this older question is the one marked as the duplicate of the newer, referenced question? Commented Jun 13, 2017 at 15:29

5 Answers 5

337

Yes. In current versions of JS you can use:

app[func]( ...args );

Users of ES5 and older will need to use the .apply() method:

app[func].apply( this, args );

Read up on these methods at MDN:

Sign up to request clarification or add additional context in comments.

6 Comments

window does not seem to be necessary.
This doesn't work if you want to call a function within an object – e.g. the following doesn't work: window.document.execCommand.apply(window,["insertHorizontalRule",false])
That's because, in your case, you should specify window.document as the first argument, not just window: window.document.execCommand.apply(window.document, ... )
window actually makes no sense in non-browser JavaScript frameworks such as NodeJS, therefore I'd suggest removing it from the answer.
If you can use ES6 features you can even use f(...[1,2,3]).
|
127

A very readable example from another post on similar topic:

var args = [ 'p0', 'p1', 'p2' ];

function call_me (param0, param1, param2 ) {
    // ...
}

// Calling the function using the array with apply()
call_me.apply(this, args);

And here a link to the original post that I personally liked for its readability

2 Comments

If that works, why won't this work? document.body.setAttribute.apply( this, ["foo", "bar"] ); I need to send variable arguments to various object methods with different argument requirements. Quick edit: Apparently this has to be document.body, or whatever the parent is
On a Typescript constructor this will raise an error: Only a void function can be called with the 'new' keyword
25
app[func].apply(this, args);

Comments

12

You might want to take a look at a similar question posted on Stack Overflow. It uses the .apply() method to accomplish this.

Comments

1

@bryc - yes, you could do it like this:

Element.prototype.setAttribute.apply(document.body,["foo","bar"])

But that seems like a lot of work and obfuscation compared to:

document.body.setAttribute("foo","bar")

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.