Skip to content
wannacode

Default values

Problem

Two items, three items

The till has to add up the prices of the items. Sometimes there are two, sometimes three. The function means the same thing either way: "add up". In Java and C# you do this with two methods that have one name and a different number of parameters. You try the same:

function total(a, b) {
return a + b;
}
function total(a, b, c) {
return a + b + c;
}
console.log(total(2.5, 4.0, 1.5));
console.log(total(2.5, 4.0));
Output
8
NaN

With three arguments it works. With two, the program does not stop, but prints NaN ("not a number"). So even with two arguments, the function with three parameters is called. Where did the first one go?

The idea

One name, one function

In JavaScript, every function is stored under its name before the first line runs. If two have the same name, the second replaces the first, again before the first line. That is why even the first call reaches the second function.

That is why JavaScript has no overloading: two functions with one name that differ in their parameters, as in Java and C#. Instead, one function can take a different number of arguments. You will see how in the next cards.

function printHeader() {
console.log("Corner Shop");
}
printHeader();
function printHeader() {
console.log("Center Shop");
}
printHeader();
Step by step, in words
  1. Before it runs a single line, JavaScript stores every function. The name printHeader points to the first one.
  2. Still before the first line: the second function with the same name. The name now points to it, and the first one is gone.
  3. Only now does the first line run. The call reaches the second function: "Center Shop".
  4. The second call: "Center Shop" again.
  5. There is one name, and the last function wins. That is why even the first call prints the new receipt.
More precisely, if you are curious

If the file has an import (like the programs that read from the keyboard), Node.js runs it as a module. There, two functions with one name are an error and the program does not start:

Error
SyntaxError: Identifier 'total' has already been declared

That is better: you see the error right away, instead of a different function being called quietly.

Try it

Which function?

What will the program print?

function describe(x) {
console.log(`whole: ${x}`);
}
function describe(x) {
console.log(`decimal: ${x}`);
}
describe(5);
describe(5.0);
Answer

The idea

A default value

One function is enough for both two and three items. Give the third parameter a default value: it is used when the argument is not passed.

function total(a, b, c = 0) {
return a + b + c;
}
console.log(total(2.5, 4.0));
console.log(total(2.5, 4.0, 1.5));
Output
6.5
8

c = 0 means: if the call has only two arguments, c is 0. If it has three, c is the third one.

Parameters with a default value are written after the ones without. Arguments are matched to parameters by position, so the optional ones go at the end.

More precisely, if you are curious

The default value is worked out on every call where the argument is missing. That is why a default array is a new one every time:

function addItem(item, cart = []) {
cart.push(item);
return cart;
}
console.log(addItem("bread"));
console.log(addItem("milk"));
Output
[ 'bread' ]
[ 'milk' ]

Try it

Find the bug

The program starts, but prints "undefined, nights: Maria". Which line is the bug on?

Pick the line with the bug.

The idea

How to skip a parameter

A hotel takes bookings. One night without breakfast is the most common, so both are defaults:

function book(name, nights = 1, breakfast = false) {
console.log(`${name}, nights: ${nights}`);
if (breakfast) {
console.log(" with breakfast");
}
}
book("Maria");
book("Ivan", 3);
book("Petya", undefined, true);
Output
Maria, nights: 1
Ivan, nights: 3
Petya, nights: 1
with breakfast

Petya wants breakfast, but only one night. JavaScript has no keyword arguments: arguments go into parameters only by position. To reach the third one, you pass undefined in place of the second. Only undefined triggers the default value. null does not:

book("Petya", null);
Output
Petya, nights: null
More precisely, if you are curious

When there are many optional parameters, JavaScript code usually passes an object with names: { breakfast: true }. In the function, { nights = 1, breakfast = false } = {} takes each value by name, with a default value. We will look at objects in the "Classes and objects" module, but the pattern is so common that it is good to recognize it:

function book(name, { nights = 1, breakfast = false } = {}) {
console.log(`${name}, nights: ${nights}`);
if (breakfast) {
console.log(" with breakfast");
}
}
book("Maria");
book("Petya", { breakfast: true });
book("Georgi", { nights: 2 });
Output
Maria, nights: 1
Petya, nights: 1
with breakfast
Georgi, nights: 2

The idea

As many arguments as you like

What if there are five items? Twenty? You do not write a parameter for each one. You say that the function takes any number of arguments:

function total(...prices) {
let result = 0;
for (const p of prices) {
result += p;
}
return result;
}
console.log(total(1.5, 2.0, 3.5, 4.0));
console.log(total(9.99));
console.log(total());
Output
11
9.99
0

The three dots before the name (...prices) mean: "pass as many values as you like". Inside the function they arrive as an array, which can also be empty. This is called a rest parameter.

function show(...prices) {
console.log(prices);
}
show(1.5, 2.0);
Output
[ 1.5, 2 ]

That is also why console.log prints as many values as you give it: it is one function that takes any number of arguments.

console.log("Bread", "Milk", "Coffee");
console.log(Math.max(3, 8, 2));
Output
Bread Milk Coffee
8
More precisely, if you are curious
  • There can be only one such parameter, and it has to be the last one: function receipt(title, ...prices).

Try it

What is missing?

function total(prices) {
  let result = 0;
  for (const p of prices) {
    result += p;
  }
  return result;
}

Exercise

One function instead of several

1. The largest. Write one function, largest(...numbers), that returns the largest of any number of numbers.

Calls
largest(3, 8)
largest(4, 9, 2)
largest(2.5, 1.5)
Output
8
9
2.5

2. Average grade. The function average(...grades) returns the average of any number of grades, and with no grades it returns 0.

Calls
average(5, 6, 4)
average(6, 5)
average()
Output
5
5.5
0

3. A receipt line. printLine(item, qty) prints "Coffee x 2". Make the quantity optional: without it, it is 1.

Calls
printLine("Coffee", 2)
printLine("Croissant")
Output
Coffee x 2
Croissant x 1

4. Free delivery. shippingCost(total, freeFrom = 50) returns 0 if the order is at least the threshold, otherwise €4.99. The threshold is €50 unless another one is passed.

Calls
shippingCost(62.0)
shippingCost(30.0)
shippingCost(30.0, 25)
Output
0
4.99
0

Test

Check yourself

1. The file has function total(a, b) { … } and below it function total(a, b, c) { … }. What does total(2, 3) give?
2. function total(a, b, c = 0) { return a + b + c; } What does total(2, 3) return?
3. How do you call function book(name, nights = 1, breakfast = false) so that there is breakfast and the nights stay at 1?
4. What is prices inside function total(...prices)?
5. Which program runs without an error but prints the wrong result?

Made by Ivo Gergov as part of Evo Tech's campaign for accessible programming education ·