---
title: Parameters
source: 'https://academia.sh/en/courses/javascript-fundamentals/parameters'
course: 'JavaScript Fundamentals'
language: en
updated: '2026-08-23T07:00:57+00:00'
license: 'CC BY-SA 4.0'
---

# Parameters

Missing and extra arguments, the condition under which default values kick in, rest parameters and spread, the arguments object, and destructured parameters.

In the previous lesson, functions were called with a fixed number of arguments.
JavaScript is loose about this: a missing argument throws no error, and neither does an
extra one. The cost of this looseness is that a missing argument stays silent.

This lesson covers parameter rules. The Programming Fundamentals course's Value and
Reference, and Passing lesson established the parameter–argument distinction and the
concept of a variable number of arguments; here, which syntax JavaScript meets these
concepts with, and which traps it carries, are shown.

## Missing and Extra Arguments

A parameter not given at the call site gets the value `undefined`. An extra argument
given is silently ignored:

```js
function report(station, threshold) {
  return `${station} / ${threshold}`;
}
console.log(report("A1"));
console.log(report("A1", 20, "extra"));
```

```
A1 / undefined
A1 / 20
```

Neither behavior produced an error. This is a deliberate decision of the language and
makes it possible for functions to behave differently based on argument count. Its cost
is that an argument left missing by a typo is only noticed once it carries an
`undefined` value into a later operation and breaks it.

## Default Values

A parameter can be given a default value. **The default kicks in only when the
argument is `undefined`** — whether it is missing or explicitly given as `undefined`.

```js
function report(station, threshold = 20) {
  return `${station} / ${threshold}`;
}
console.log(report("A1"));
console.log(report("A1", undefined));
console.log(report("A1", null));
console.log(report("A1", 0));
console.log(report.length);
```

```
A1 / 20
A1 / 20
A1 / null
A1 / 0
1
```

The third and fourth lines show that this is a narrower criterion than even the `??`
operator from the Truthiness lesson: not even `null` triggers the default. The value
`0` also passes through — default values naturally avoid the trap that a fallback
assignment written with `||` would fall into.

The last line shows that the `length` property gives the parameter count **before**
the parameter with a default.

Default expressions are **re-evaluated on every call** and can use the parameters that
come before them:

```js
let counter = 0;
function next() {
  counter += 1;
  return counter;
}
function label(name, sequence = next()) {
  return `${name}-${sequence}`;
}
console.log(label("A1"));
console.log(label("A2"));
console.log(label("B1", 99));
console.log(label("B2"));
```

```
A1-1
A2-2
B1-99
B2-3
```

In the third call, `next` was never called because an argument was given; the counter
did not increase. This is proof that a default is evaluated at call time and only when
needed.

A default resting on a previous parameter is useful in range definitions:

```js
function range(low, high = low + 5) {
  return [low, high];
}
console.log(range(18));
console.log(range(18, 30));
```

```
[ 18, 23 ]
[ 18, 30 ]
```

The order is one-directional: a parameter can refer only to parameters written
**before** it.

A default expression being evaluated at call time also opens a way to declare required
parameters:

```js
function required(name) {
  throw new Error(`${name} parameter is required`);
}
function save(station = required("station"), temperature = required("temperature")) {
  return `${station}=${temperature}`;
}
console.log(save("A1", 21.5));
try {
  save("A1");
} catch (error) {
  console.log(error.name + ": " + error.message);
}
```

```
A1=21.5
Error: temperature parameter is required
```

When an argument is given, the default expression never runs; when it is not given, an
error is thrown. Error objects and the `throw` statement are covered in this topic's
last lesson.

## Rest Parameters and Spread

Arguments whose count is not known in advance are collected with a **rest
parameter**. The three-dot spelling puts all remaining arguments into a real array:

```js
function highest(label, ...readings) {
  return `${label}: ${Math.max(...readings)} (${readings.length} readings)`;
}
console.log(highest("A1", 21.5, 19.75, 23));
console.log(highest("B1"));
console.log(highest.length);
```

```
A1: 23 (3 readings)
B1: -Infinity (0 readings)
1
```

The second line shows an edge case: called with no readings, `readings` is an empty
array, and `Math.max()` gives `-Infinity`. This is mathematically consistent — the
maximum of an empty set returns the neutral element — but is meaningless in a
measurement context. An empty-list check should be written.

The same three dots work in the opposite direction at the call site: they spread an
array into separate arguments.

```js
function highest(label, ...readings) {
  return `${label}: ${Math.max(...readings)}`;
}
const temperatures = [21.5, 19.75, 23, 18.25];
console.log(highest("all", ...temperatures));
```

```
all: 23
```

The two uses should not be confused. Three dots in a parameter list **collect**; three
dots at a call site **spread**. The same syntax's two directions are told apart by
where they sit.

A rest parameter can only be in the last position and is not counted toward the
`length` property.

## The Arguments Object

Before rest parameters, a variable number of arguments was read through an implicit
object called `arguments`. This object still exists and is found in older code:

```js
function oldForm() {
  console.log(typeof arguments, arguments.length);
  console.log(Array.isArray(arguments));
  console.log(Array.from(arguments));
}
oldForm(21.5, 19.75);
```

```
object 2
false
[ 21.5, 19.75 ]
```

The second line is the problem itself: `arguments` is not an array. It has a length
and indices, but no array methods; it has to be converted to an array first to be used.

A second problem shows up with default values:

```js
function withDefault(a = 1) {
  console.log("arguments.length:", arguments.length, "a:", a);
}
withDefault();
withDefault(5);
```

```
arguments.length: 0 a: 1
arguments.length: 1 a: 5
```

`arguments` only counts the arguments **actually given**; it does not see a parameter
filled in by a default. The two sources of information diverge, and which one to read
becomes unclear.

Third, `arguments` is not found at all in arrow functions — this topic's next subject.
In this course, a variable number of arguments will always be written with a rest
parameter.

## Destructured Parameters

In a function taking more than three or four parameters, the call line becomes
unreadable: the order has to be memorized. The solution is to gather the options into
an object and unpack it in the parameter list through **destructuring**:

```js
function summarize({ station, temperature, unit = "C" }) {
  return `${station}: ${temperature} ${unit}`;
}
console.log(summarize({ station: "A1", temperature: 21.5 }));
console.log(summarize({ station: "A2", temperature: 19.75, unit: "K" }));
```

```
A1: 21.5 C
A2: 19.75 K
```

The call line now states which value is which on its own, and order no longer matters.
Defaults can be given to individual fields one by one.

This spelling has a trap: if the argument is not given at all, destructuring tries to
operate on `undefined`:

```js
function summarize({ station, temperature }) {
  return `${station}: ${temperature}`;
}
try {
  console.log(summarize());
} catch (error) {
  console.log(error.name + ": " + error.message);
}
```

```
TypeError: Cannot destructure property 'station' of 'undefined' as it is undefined.
```

The fix is to give the entire parameter an empty-object default:

```js
function summarizeSafe({ station = "?", temperature = null } = {}) {
  return `${station}: ${temperature}`;
}
console.log(summarizeSafe());
console.log(summarizeSafe({ station: "B1" }));
```

```
?: null
B1: null
```

Two layers of defaults work together: the outer `= {}` kicks in if the object itself
is missing, the inner ones kick in if individual fields are missing.

If all of a function's options are required, the outer default is not written; then a
missing call throws an error, and this is the intended behavior. The choice depends on
what the contract is.

## Summary

- A missing argument becomes `undefined`, an extra argument is ignored; neither
  produces an error.
- A default value kicks in only when the argument is `undefined`; `null` and `0` do
  not trigger the default.
- Default expressions are evaluated on every call and only when needed; they can use
  the parameters before them.
- A rest parameter collects arguments into a real array and must be last; three dots
  at a call site work in reverse, spreading an array into arguments.
- The `arguments` object is not an array and does not count parameters filled by a
  default; this course uses rest parameters.
- A destructured parameter provides named options; if the whole object has no default,
  a call with no arguments throws an error.

## Next Step

Short forms like `(d) => d > threshold` were used unexplained in this lesson. The next
lesson covers arrow functions: the forms of the short syntax, the implicit return rule,
and the difference these functions have from the `arguments` object and from context
behavior. The difference is not just brevity — an arrow function cannot be used in some
places.
