Wes Bos

I just launched a new course on ES6! Use the code WESBOS for \$10 off.

JavaScript Default Function Arguments

Sep 11 2016

Default function arguments in JavaScript are here. This is one of those features that’s going to make your life much easier, and make your code much more readable and maintainable.

Let’s say we have a function called `calculateBill` which is going to take in three things: the `total` cost of your meal, how much `tax` we need to pay, and then how much you would like to `tip` your waiter:

``````function calculateBill(total, tax, tip) {
}
``````

From that, we can return the total amount of hte bill.

Then we’ll make a new variable called `totalBill`, and we’ll use our new function, to figure out how much all of that costs.

``````function calculateBill(total, tax, tip) {
}

const totalBill = calculateBill(100, 0.13, 0.15);
console.log(totalBill);
``````

On a \$100 meal, with 13% tax and a 15% tip, the console will tells us `128`, or \$128.

What happens if we want to automatically assume 13% tax rate, and we want to assume a 15% tip rate?

What we could do is just pass in our \$100 meal and get our result. If we omit `tax` and `tip``calculateBill(100)` our function returns us `NaN`, or “not a number”. That’s because we’re trying to do math against things that aren’t passed in.

``````function calculateBill(total, tax, tip) {
console.log(tax);
}

const totalBill = calculateBill(100);
console.log(totalBill);
``````

If you use `console.log` to show the value of `tax` or `tip`, you’ll see that they show up as `undefined`.

What we would normally do is we would add an `if` loop:

``````function calculateBill(total, tax, tip) {
if(tax === undefined) {
tax = 0.13;
}
if(tip === undefined) {
tip = 0.15;
}
}

const totalBill = calculateBill(100);
console.log(totalBill);
``````

It works fine there, but there’s a whole lot of code that we added.

You might be saying, “Yeah, you can do this, tax equals tax,” or you can do this little trick here where you can say it equals itself.

``````function calculateBill(total, tax, tip) {
tax = tax || 0.13;
tip = tip || 0.15;
}

const totalBill = calculateBill(100);
console.log(totalBill);
``````

I don’t mind that, but it can be a little bit hard on your team to have to read it. If you’ve got four or five different arguments coming in, then you’ve got to do all this crazy code at the top.

Another thing to note is the `||` trick will fallback to the default if you pass in `0`, `null`, `false` or any other falsy value. Not exactly what you want when you are trying to tip \$0!

So let’s just do without that entirely. What we can do now in ES6 is just simply set it when we define our function, and those things will be assumed.

``````function calculateBill(total, tax = 0.13, tip = 0.15) {
}

const totalBill = calculateBill(100);
console.log(totalBill);
``````

If nothing is passed in for that one, then the defaults are going to go ahead. There we’re good to go.

What else we can do?

What if I wanted to pass only the total amount, as well as the tip amount, because I’m a big tipper. Let’s say I’m tipping 25% here, and the tax rate isn’t going to change because I’m still in Ontario.

However, if I just leave the tax empty, we’ll get a syntax error, like I would here:

``````function calculateBill(total, tax = 0.13, tip = 0.15) {
}

const totalBill = calculateBill(100, , 0.25);
console.log(totalBill);
``````

How do you leave a hole in here?

Well, what does this essentially check for? It checks for tax being passed `undefined` so you can just explicitly pass `undefined`:

``````function calculateBill(total, tax = 0.13, tip = 0.15) {
}

const totalBill = calculateBill(100, undefined, 0.25);
console.log(totalBill);
``````

The function is going to say, “Oh, no one passed any tax.” our default 13% and then the big tip is going to kick in here, and we get `138`, or \$138.

I’ve got another example similar to this one where this is order dependent, and when we hit destructuring, I’m going to show you how do you use an object in destructuring, so that you could pass this in any order, as well as have default arguments. But more on that later.

This entry was posted in ES6, JavaScript. Bookmark the permalink.

4 Responses to JavaScript Default Function Arguments

1. MaxArt says:

Pro-tip: instead of using undefined, you can always use `void 0`, which is shorter, or even better:

let _;
const totalBill = calculateBill(100, _, 0.25);

Of course, if _ has already been taken by Lodash/Ramda/whatever, you can stick to whatever you like.
The underscore is just more expressive as a placeholder.

• wesbos says:

Not sure I like void 0 or having to declare an undefined variable before using it – it’s not immediately as clear as using undefined. But to each their own – others may enjoy this way 🙂

Nice Pro-tip MaxArt! Although using an “undefined” without declaration represents the primitive undefined, it can be hijacked in the global scope and then cause inconsistencies in the API for calculateBill.

Passing in an “undefined” parameter, be it declared or not, in order to trigger a default state of a call signature for the calculateBill routine seems a bit of a kluge.

Although ES6 provides this functionality, I would say placing multiple default values next to each other in the parameters should be reconsidered.

By swapping tax and tip and not providing tip with default parameter, as follows:

function calculateBill( total, tip, tax = 0.13){ … }

you simple have to omit passing in the variable all together.

calculateBill( 100, 0.15 );
//Here tax will be set to the default value

What would be better yet would be to pass in a single object of all the optional components, and actually write all the “extra” code to do the default checking for you.

function calculateBill( total, optionalArgs ){
var tax = optionalArgs.hasOwnProperty(“tax”) ? optionalArgs.tax : 0.13;
var tip = optionalArgs.hasOwnProperty(“tip”) ? optionalArgs.tip : 0.15;
}

var total = 100;
var optArgs = {};

optArgs.tip = 0.15;
optArgs.tax = 0.13;

var totalBill = calculateBill( total, optArgs );

Keep in mind that you could also just pass in a single option argument with all three parameters in them.

JS 101 will tell you this is not good to pass around undeclared variables into a function. Please refrain from encouraging bad practice for people getting into JavaScript, especially with all the fancy new features newer versions are providing.

2. Eduardo Lourenço says:

Nice work! But personally, I prefer:

function calculateBill({total, tax = 0.13, tip = 0.15}) {