Rest arguments and default arguments in JavaScript

In the last two weeks, Benjamin Peterson has implemented two new features in the JavaScript engine. You want to know about these. If you write a lot of JS, they will make your life better.

Rest arguments are a nicer substitute for the familiar arguments object. The syntax looks like this:

function f(arg1, arg2, ...rest) {
    alert("You passed " + rest.length + " extra arguments.");
}

This works just like rest-arguments in Python, Lisp, and Ruby. Each time you call f, the first few arguments are assigned to the ordinary arguments, in this case arg1 and arg2. Any extra arguments you pass are stored in an array, rest. If you don’t pass any extra arguments, rest is an empty array.

Unlike the arguments object, a rest-argument is a real Array. It has all the Array methods, including .shift(), .forEach(), and .map(). And unlike arguments, which is re-defined in each nested function whether you want it or not, a rest-argument works exactly as expected in a closure.

Default arguments look like this:

function fade(element, seconds=0.5, targetOpacity=0) {
    $(element).animate({opacity: targetOpacity}, seconds * 1000);
}

When you call this function, if you omit the arguments that have default values, they’ll get the default values.

fade(form, 0.2, 1);  // default values are not used:
                     // fade in fast
fade(form, 3);       // targetOpacity defaults to 0:
                     // fade out very slowly
fade(form);          // seconds defaults to 0.5,
                     // targetOpacity defaults to 0:
                     // fade out at normal speed

The default value can be any expression. It can use the values of preceding arguments, as in

function logEvent(event, logger=findLoggerFor(event.target)) {
    ...
}

where the default value of logger depends on the event argument.

(Extreme technical details: Note that unlike Python, the default value is computed each time the function is called, so if an argument has =[], it gets a fresh empty Array each time. Also, note that currently you only get the default value if the caller actually leaves off the argument. If the caller explicitly passes undefined, the argument’s value is undefined and the default is ignored. But there is some discussion on the committee about maybe changing that so that the default is also used when the caller explicitly passes undefined. Other programming languages don’t do this, but it would fit with what the DOM already does in many cases. Right now we follow the current proposal; if the proposal changes, we’ll update our implementation.)

Both of these new features are on track to become part of the next ECMAScript standard.

Benjamin is still going strong. There’s more to come.

5 Responses to Rest arguments and default arguments in JavaScript

  1. “Extreme technical details”

    that’s not extreme technical detail, especially since you allow non-primitive types to be default values. it was the first thing i thought of once i saw the second example..

    “default is also used when the caller explicitly passes undefined”

    this could be useful if i want to pass last argument, but am ok with default value for the second-to-last one..

  2. Nicholas Nethercote

    Nice!

  3. Default argument values are a good news. The rest arg too. Good job ! Wich it’ll soon be available in every modern browsers.

  4. This is great! The only thing missing is keyword arguments to functions, which (IMO) are critical to making default arguments work. (e.g. To handle the situation tom jones described, especially with long lists of arguments which you see in Python quite frequently — no doubt because they have keyword arguments!)

  5. Calvin Spealman

    Is this in any actual EMCA/JS specs?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>