–VIDEO TRANSCRIPT–
In this video I’ll demonstrate how to set default values for function parameters.
Some programming languages let you define a function with default parameter values like this:
public void AddToCart(string productName, decimal price, int quantity = 1, string currency = "USD") {
// logic here
}
In fact, with ES2015 we can now do very much the same thing.
A nice feature in other languages that is not available in JavaScript is calling a function with named parameters.
Named parameters let us quickly override default parameter values.
To call this function and override the currency value but accept the default values for all other parameters preceding it would look something like this:
AddToCart("Bicycle", 100.00, currency: "CAD");
I call AddToCart with a product name and a price. Then I supply the function a currency parameter with the value of ‘CAD’ for Canadian Dollars.
The value of the quantity parameter will be 1 as that is the default value in the function’s signature.
In JavaScript, specifically ES2015, we now have access to default parameters. In addition, we also have destructuring which provides a way to extract the values we need.
What I’m going to show you won’t work in ES5 so you’ll need a transpiler like Babel or TypeScript.
I’ll be using TypeScript here but you can find the ES2015 solution in the notes below.
First let’s look at how to use default parameters.
I’ll create a addToCart function.
function addToCart(product: string, price: number, quantity = 1, currency = 'USD') {
...
}
And I’ll console log all of the parameters so I can see it in action.
function addToCart(product: string, price: number, quantity = 1, currency = 'USD') {
console.log(product, price, quantity, currency);
}
This is very similar to the C# example I showed earlier. The main differences are in the type annotations which you can ignore if you aren’t using TypeScript.
Now I’ll call the function and take the default parameters just to know everything is working.
addToCart('Bicycle', 99.99);
Perfect! The console log shows the values I expected.
Now I’ll call it again, but this time I’ll change the currency to Canadian Dollars.
addToCart('Bicycle', 99.99, currency = 'CAD');
It looks like the TypeScript language service isn’t happy with my function call.
If I put my mouse over the code I can see what the issue is.
It’s trying to interpret our currency as the quantity parameter.
JavaScript, as well as TypeScript, doesn’t support this kind of assignment in a function call.
Instead I’ll need to provide a value for all the parameters preceding currency.
addToCart('Bicycle', 99.99, undefined, 'CAD');
When I pass a parameter an undefined value JavaScript will use the default value for that parameter.
This can be confusing when looking at the code later on.
To work around this limitation of JavaScript we can use destructuring to handle our default values and the power of TypeScript to manage our required parameters.
First I’ll start by creating an interface for our function parameters.
My interface will define the parameter names and their types.
I can’t include default values here since the interface will be discarded in the transpiled JavaScript.
interface AddToCartParameters {
product: string;
price: number;
quantity?: number;
currency?: string;
}
I’ll use the question mark to indicate the optional parameters. These are the parameters that will have default values in the function’s signature.
Then I’ll update my function parameters.
With destructuring I can set a default parameter with our AddToCartParameters
interface.
function addToCart({ product, price, quantity, currency }: AddToCartParameters) {
console.log(product, price, quantity, currency);
}
And I’ll call it like this:
addToCart({ product: 'Bicycle', price: 99.99 });
The console log shows the output with quantity and currency being undefined. That’s to be expected since I didn’t provide default values in the function definition.
I’ll add them now.
function addToCart({ product, price, quantity = 1, currency = 'USD' }: AddToCartParameters) {
console.log(product, price, quantity, currency);
}
Now the console log shows the default values for both quantity and currency.
Since this function takes an object I can compose the parameters object however I like.
I’ll create a parameters object for a series of products.
let Bicycle = {
product: 'Bicycle',
price: 99.99
}
let Helmet = {
product: 'Helmet',
price: 33.33
}
let Bell = {
product: 'Bell',
price: 11.11
}
Now I’ll add all of these products to the cart but I’ll change the currency to Canadian Dollars.
Array(Bicycle, Helmet, Bell).forEach(product => {
let cartParams: AddToCartParameters = Object.create(product);
cartParams.currency = 'CAD';
addToCart(cartParams);
});
One thing that may cause you pain with this approach is the need to always provide a named parameter. It doesn’t need to be this way.
I’ll split up the function’s parameters making the required parameters separate from the default parameters.
Now that my object will only have default parameters I don’t need the rely on the interface anymore. Instead I’ll let TypeScript infer the types from the default values. This reduces the amount of code I need to maintain.
function addToCart(product: string, price: number, { quantity = 1, currency = 'USD' }) {
console.log(product, price, quantity, currency);
}
And I’ll update the loop that adds the products to the cart.
Array(Bicycle, Helmet, Bell).forEach(product => {
addToCart(product.product, product.price, { currency: 'CAD' });
});
I’ll save it. The console is showing the correct information.
While JavaScript doesn’t have named parameters baked in, this approach gets us pretty close.