Handling a function with a variable number of arguments is always tricky in JavaScript. At least, we still have this arguments
object which can be used to retrieve all arguments used to invoke a function. With the upcoming ECMAScript 6, no such hack is necessary anymore since we can start using its rest parameter feature.
To see how a rest parameter works, consider the following scenario. You drive a truck which delivers some supplies to a grocery store. As you unload the supplies, you add them to the store:
store.add('fruit', 'apple');
store.add('dairy', 'milk', 'cheese', 'yoghurt');
store.add('pastries', 'donuts', 'croissants');
whereby add
is implemented as something like:
store.add = function(category) {
var items = [].slice.call(arguments, 1);
items.forEach(function (item) {
store.aisle[category].push(item);
});
};
Note how arguments object can’t be treated as a normal array, although it behaves almost like an array. A well-known trick with Array.prototype.slice and Function.prototype.call is the workaround, giving us the list of all arguments which comes after the first one (category).
With a rest parameter (Section 13.1, ES 6 draft Rev 13), the implementation is much simpler. It is even self-explanatory.
store.add = function(category, ...items) {
items.forEach(function (item) {
store.aisle[category].push(item);
});
};
Another typical use-case where a rest parameter could be useful is a pubsub-like pattern. If you write a Backbone.js-based application, triggering an event via Backbone.Event.trigger is a common practice. Because an event may require one or more parameters, the implementation of the trigger function itself looks like:
trigger: function(name) {
if (!this._events) return this;
var args = slice.call(arguments, 1);
/// ... do something with args ...
return this;
},
for which I’m sure you can come up with a slightly different look if you have the rest parameter feature as your disposal!
Obviously we don’t need a rest parameter if we switch the API to accept an array as the second argument. However, in some cases, it would feel less natural. For example, a string formatter implementation is expected to follow the de-facto printf format string rather than grouping every parameters in a simple array.
Just like other syntactic sugar in ECMAScript 6, a rest parameter does not radically change you write your JavaScript code. It does however make the code more tool-friendly, shifting the semantic interpretation of the code from the run-time behavior into something at the syntax level. Once editors and IDEs understand the construct, a simple code hint which reveals the function signature is more than enough to indicate that the said function accepts a variable number of arguments.
Isn’t it exciting?