JavaScript argument unpacking: converting an array into a list of arguments
Posted on August 17th, 2008 in JavaScript | 3 Comments »
Ruby has a cool operator by the name of splat(*) that lets you unpack an array as arguments on the fly. See this code below for an example:
# Define the item array item1 = ['Jack', '39', 'Panda'] # Define a regular function that takes three arguments def hi(name, age, type) puts 'Hi ' + name + '! You are ' + age + ' and a ' + type + '!' end # Call the function using item1 and the splat operator hi(*item1) # Outputs: Hi Jack! You are 35 and a Panda!
While JavaScript does not have such a convenient operator, experimenting around, I’ve found a good enough solution:
var item1 = ['Jack', '39', 'Panda']; function hi(name, age, type){ console.log('Hi ' + name + '! You are ' + age + ' and a ' + type + '!'); } hi.apply(this, item1); // Outputs to your Firebug console: Hi Jack! You are 39 and a Panda!
The apply method is built into all functions in JavaScript and allows you to call a method of an object in the context of a different object (Moz dev page here). Think about it as the equivalent of temporarily moving that method off the current object (the window object if it’s a global function) and attaching it to another object before calling it.
The primary reason to use this method is for changing the this keyword reference inside of the called function, but it has the added benefit of optionally requiring an array of arguments that get passed to the called function. We basically keep the this keyword as the window object (could have specified window instead of this) and use it to unpack our array for us.
This solution is also useful in any situation where you have a function that takes an unlimited number of arguments and you want to to eventually send those arguments to another function that also accepts any number of arguments. This situation is exactly what was puzzling me as I was working on creating a “safe” version of Firebug’s console.log that would work normally in Firefox but alert each argument separately in Internet Explorer.
Lastly, this is usefully for succinct array merging. Instead of looping through one array and pushing each item onto another you can do:
bob = [1,2,3,4]; sue = ['a','b']; bob.push.apply(bob,sue); bob // returns [1,2,3,4,a,b]
3 Responses
This is probably better for array merging.
bob = bob.concat(sue);Thanks James. The Array.concat method is a little different as it returns to you a new Array object as apposed to just adding to the existing array1.
For most cases I think the .concat is fine but for extremely complex arrays it may be better to not make a copy. I haven’t tested this, though.
[...] how to fix up some of my function shortcuts to take any number of arguments (similar to this argument unpacking entry on how to do it in JavaScript and [...]