ariya.io About Talks Articles

ECMAScript 6 and Default Argument

3 min read

Many programming languages support the concept of a default argument for a function parameter so that the caller does not always need to specify the argument value. Unfortunately, JavaScript does not have a default argument support in its syntax. This may soon change with the upcoming ECMAScript 6.

A few JavaScript programmers employ various different run-time tricks to achieve the effect of an argument with a default value. The common approach is by leveraging the fact that if an argument is not given a value, then it’s simply undefined.

function foobar(a) { return typeof a; }
foobar(); // "undefined"

This can lead to some code like:

function runApp(appName) { console.log('Running', appName || 'AUTOEXEC.BAT'); }

That function will print Running AUTOEXEC.BAT if invoked as runApp() only (without any argument). The use of logical expression OR (operator ||, see section 11.11 on Binary Logical Operators) means that if the left side (appName) is true (see section 9.2 on ToBoolean), then the short-circuiting kicks in, otherwise we will get the right side (AUTOEXEC.BAT). Note how the result is the same if you execute that function with other value such as null, `,![], or even~~{}`.

Another variant which are often encountered is really checking the type of the parameter. Now we can distinguish between undefined and others. Therefore, a suitable value substitution can be carried out.

function runApp(appName) {
  if (typeof appName === 'undefined') appName = 'AUTOEXEC.BAT';
  console.log('Running', appName);
}

In other cases, we really really need to know whether the function is invoked with a certain number of argument or not. For this purpose, the arguments object comes to the rescue.

function runApp(appName) {
  if (arguments.length === ) appName = 'AUTOEXEC.BAT';
  console.log('Running', appName);
}

All this fancy dance is not necessarily anymore once the syntax itself supports a default argument. In the section 13 of the latest ECMAScript 6 draft, it is mentioned that the formal parameter (for a function) is not a simple list of identifiers anymore (as in ECMAScript 5) as it is generalized to allow BindingElement. While this new construct is there to permit the object and array pattern (see my previous blog post on destructuring assignment), it is important to realize that BindingElement supports an optional initialization, pretty much like in a variable declaration.

In plain English, this means that a function declaration can specify a default value for every parameter. The previous runApp function will turn into something as simple as:

function runApp(appName = 'AUTOEXEC.BAT') {
  console.log('Running', appName);
}

While waiting for browsers and JavaScript engines to implement this feature, such a construct can be used already these days with help of Traceur or TypeScript. It is interesting to note the different desugaring, Traceur will use the arguments object while TypeScript performs the undefined type check.

Having a built-in syntax support for default argument is fantastic. A JavaScript editors could give a better content assist (autocomplete). A code analyzer will be able to track function invocation which omits parameters that do not have default values. I can’t wait until a linter complains to me:

guide.js:42 Specify the non-optional parameter 'stop' to function 'createSeries'

Better language tools will no doubt reduce any coding mistake as best as it can.

Related posts:

♡ this article? Explore more articles and follow me Twitter.

Share this on Twitter Facebook