---
type: reference
language: javascript
slug: function/parameters
title: "関数の引数 — 既定値・可変長・分割代入"
title_tag: "JavaScript 関数の引数 — 既定値と残余引数の使い方"
summary: >
  既定値が働くのは undefined のときだけです。null では働きません。可変長引数の受け取り方、
  オブジェクトで受けて名前を付ける書き方、length が数えない引数までを実行して確かめます。
description: >
  既定値は undefined のときだけ働き、null では働きません。残余引数で可変長を受ける形、
  オブジェクトで受けて呼び出し側から読めるようにする書き方まで実行して確かめられます。
status: published
difficulty: 2
minutes: 8

versions:
  verified: "Node 22.22.3"
  since: "ES2015"
  deprecated: null
  removed: null

sources:
  - title: "Function Definitions — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-function-definitions"
  - title: "Rest Parameters — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-function-definitions-static-semantics-expectedargumentcount"
  - title: "デフォルト引数 — MDN"
    url: "https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/Default_parameters"

terms: [既定値, 残余引数, 分割代入, アリティ]

links:
  related:
    - javascript/learn/object/nested
    - javascript/why/this-binding
    - javascript/errors/is-not-a-function
    - javascript/learn/function/basics

content_updated_at: 2026-09-08
published_at: 2026-09-08
---

`=` で既定値を書けます。**働くのは `undefined` のときだけ**です。

```js run
function greet(name = 'あなた', mark = '!') {
  return name + mark;
}

console.log(greet());
console.log(greet('あ'));
console.log(greet(undefined, '?'));
```
```output
あなた!
あ!
あなた?
```

`undefined` を渡すと[key:渡していないのと同じ]扱いになります。
だから「2番目だけ指定したい」ときに `undefined` を書けます。

## `null` では働かない

```js bad
function greet(name = 'あなた') {
  return name + '!';
}

console.log(greet(null));
```
```output
null!
```

**`null` は「値として渡された」ので、既定値に置き換わりません。**

`null` も既定値にしたいなら `??` を使います。

```js run
function greet(name) {
  return (name ?? 'あなた') + '!';
}

console.log(greet(null));
console.log(greet(undefined));
console.log(greet(''));
```
```output
あなた!
あなた!
!
```

空文字はそのまま通ります。`||` にすると空文字も置き換わるので注意してください。
→ [なぜ typeof null は "object" なのか](/ja/javascript/why/typeof-null/)

## 何個でも受け取る

`...` を付けた引数（[type:残余引数]）は、**残り全部を配列で受けます。**

```js run
function sum(...nums) {
  return nums.reduce((total, n) => total + n, 0);
}

console.log(sum());
console.log(sum(1));
console.log(sum(1, 2, 3));
```
```output
0
1
6
```

**渡されなければ空配列**です。`undefined` にはなりません。

前に固定の引数を置けます。**残余引数は最後にしか書けません。**

```js run
function head(first, ...rest) {
  return [first, rest];
}

console.log(head(1, 2, 3));
console.log(head(1));
```
```output
[ 1, [ 2, 3 ] ]
[ 1, [] ]
```

[dim:古い書き方の `arguments` は、アロー関数では使えず、配列でもありません。新しく書くなら残余引数を使ってください。]

## オブジェクトで受ける

引数が[num:3]つを超えたら、**オブジェクトで受けるほうが読みやすくなります。**

```js run
function show({ name, city = '不明' } = {}) {
  return `${name}／${city}`;
}

console.log(show({ name: 'あ', city: '東京' }));
console.log(show({ name: 'い' }));
console.log(show());
```
```output
あ／東京
い／不明
undefined／不明
```

- **呼び出し側から「何を渡しているか」が読めます**
- 順番を覚えなくてよくなります
- あとから項目を足しても、既存の呼び出しが壊れません

`= {}` を付けているのは、**引数そのものを省けるようにする**ためです。
付けないと、何も渡さなかったときに落ちます。

```js bad
function show({ name }) {
  return name;
}

console.log(show());
```
```output
TypeError: Cannot destructure property 'name' of 'undefined' as it is undefined.
```

→ [入れ子のオブジェクトを安全に扱う](/ja/javascript/learn/object/nested/)

## `length` は全部を数えない

```js run
function f(a, b = 1, ...c) {}
function g(a, b) {}

console.log(f.length);
console.log(g.length);
```
```output
1
2
```

`length` が数えるのは、**既定値と残余引数が出てくる前まで**です。
`f` は3つ書いてあるのに `1` です。

[bad:「この関数は何個の引数を取るか」の答えとしては使えません。]
[dim:引数の個数に応じて処理を変えたいなら、残余引数で受けて `nums.length` を見てください。]

## 余分に渡しても落ちない

```js run
function add(a, b) {
  return a + b;
}

console.log(add(1, 2, 3, 4));
console.log(add(1));
```
```output
3
NaN
```

**多すぎても少なすぎても例外になりません。**

足りない分は `undefined` になり、計算に使うと `NaN` になります。
[em:「呼び方を間違えても動いてしまう」ので、既定値を書いておく価値があります。]

```js run
function add(a = 0, b = 0) {
  return a + b;
}

console.log(add(1));
```
```output
1
```

## 既定値には式が書ける

```js run
function makeTag(name, label = name.toUpperCase()) {
  return `${name}:${label}`;
}

console.log(makeTag('a'));
console.log(makeTag('a', 'B'));
```
```output
a:A
a:B
```

**前の引数を使えます。** 評価されるのは[key:呼ばれたとき]なので、
毎回新しい値になります。

[bad:ただし後ろの引数は使えません。] まだ決まっていないからです。

## よくある間違い

### 既定値にオブジェクトを書いて共有されると思う

```js run
function push(value, list = []) {
  list.push(value);
  return list;
}

console.log(push(1));
console.log(push(2));
```
```output
[ 1 ]
[ 2 ]
```

**毎回新しい配列が作られます。** 前の呼び出しの結果は残りません。

[dim:他の言語では既定値が1度だけ評価され、共有されてしまうものがあります。JavaScript は呼ばれるたびに評価します。]

### 引数を書き換える

```js bad
function addTax(price) {
  price = price * 1.1;
  return price;
}

const original = 100;

console.log(addTax(original));
console.log(original);
```
```output
110.00000000000001
100
```

数値は複製されるので元は変わりません。**ですがオブジェクトは変わります。**

```js bad
function rename(user) {
  user.name = '変えた';
  return user;
}

const user = { name: 'あ' };

rename(user);

console.log(user);
```
```output
{ name: '変えた' }
```

**受け取ったオブジェクトを書き換えないでください。**
新しいものを返すほうが、呼び出し側から見て安全です。

```js run
function rename(user, name) {
  return { ...user, name };
}

const user = { name: 'あ' };

console.log(rename(user, '変えた'));
console.log(user);
```
```output
{ name: '変えた' }
{ name: 'あ' }
```

## まとめ

- 既定値が働くのは[key:`undefined`]のときだけ。**`null` では働かない**
- `null` も含めるなら `??`
- `...rest` は残り全部を配列で受ける。**無ければ空配列**
- 引数が多いなら**オブジェクトで受ける**。`= {}` を忘れない
- `length` は既定値の手前まで。**引数の個数ではない**
- 多すぎても少なすぎても落ちない。足りない分は `undefined`
- **受け取ったオブジェクトを書き換えない**
