---
type: learn
language: javascript
slug: function/basics
title: "関数の基本 — 作る・呼ぶ・返す"
title_tag: "JavaScript 関数の基本 — 3つの書き方と戻り値【第1回】"
summary: >
  関数の3つの書き方と、それぞれで変わること。戻り値を書き忘れたときに何が返るか、
  アロー関数でオブジェクトを返すときの落とし穴までを、実行しながら確かめます。
description: >
  function 宣言だけが定義より前で呼べます。アロー関数で {} を書くと return が要る理由、
  オブジェクトを返すのに丸括弧が要る理由まで、実行しながら確かめられます。
status: published
difficulty: 1
minutes: 9

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

sources:
  - title: "Function Definitions — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-function-definitions"
  - title: "Arrow Function Definitions — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-arrow-function-definitions"
  - title: "関数 — MDN"
    url: "https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Functions"

terms: [関数宣言, 関数式, アロー関数, 戻り値, 巻き上げ]

links:
  prev: null
  next: javascript/learn/function/scope
  related:
    - javascript/reference/function/parameters
    - javascript/learn/array/basics

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

関数は、**まとまった処理に名前を付けて、何度でも呼べるようにする**しくみです。

```js run
function double(n) {
  return n * 2;
}

console.log(double(3));
console.log(double(10));
```
```output
6
20
```

`(n)` が[key:受け取るもの]、`return` が[key:返すもの]です。

## 書き方は3つある

```js run
function declared(n) {
  return n * 2;
}

const expression = function (n) {
  return n * 2;
};

const arrow = (n) => n * 2;

console.log(declared(1), expression(1), arrow(1));
```
```output
2 2 2
```

**結果は同じ**です。違うのは書き方と、次の2点だけです。

| | 定義より前で呼べる | `this` |
|---|---|---|
| `function` 宣言 | **呼べる** | 呼ばれ方で決まる |
| 関数式（`const f = function`） | [bad:呼べない] | 呼ばれ方で決まる |
| アロー関数（`const f = () =>`） | [bad:呼べない] | **持たない** |

## 定義より前で呼べるかどうか

`function` で書いた関数は、**丸ごと先に読まれます。**

```js run
console.log(hoisted(1));

function hoisted(n) {
  return n + 1;
}
```
```output
2
```

`const` に入れた関数はそうなりません。

```js bad
notYet(1);

const notYet = (n) => n + 1;
```
```output
ReferenceError: Cannot access 'notYet' before initialization
```

**同じ「関数」でも書き方で挙動が違います。**
→ [ReferenceError: Cannot access 'x' before initialization](/ja/javascript/errors/cannot-access-before-initialization/)

[em:迷ったら、定義を使うところより上に書いてください。] そうすれば書き方に左右されません。

## 返さないと `undefined`

```js run
function nothing() {
  console.log('動いた');
}

const result = nothing();

console.log(result);
```
```output
動いた
undefined
```

`return` が無い関数は `undefined` を返します。**エラーにはなりません。**

`return` は[key:そこで関数を抜けます]。あとの行は実行されません。

```js run
function check(n) {
  if (n < 0) {
    return '負';
  }

  return '正か0';
}

console.log(check(-1));
console.log(check(0));
```
```output
負
正か0
```

**先に返して抜ける書き方**は、入れ子を浅くできるのでよく使われます。

## アロー関数の `{}` に注意

アロー関数は、`{}` を書くかどうかで意味が変わります。

```js run
const short = (n) => n * 2;
const block = (n) => {
  n * 2;
};

console.log(short(2));
console.log(block(2));
```
```output
4
undefined
```

- `{}` **なし** … その式の値が[em:そのまま返る]
- `{}` **あり** … ふつうの関数と同じ。`return` が要る

[bad:`{}` を書いて `return` を忘れる]のは、いちばん多い間違いです。
`map()` で `undefined` が並ぶのも同じ原因です。
→ [Array.prototype.map()](/ja/javascript/reference/array/map/)

### オブジェクトを返すときは丸括弧

```js bad
const wrong = (n) => { value: n };

console.log(wrong(1));
```
```output
undefined
```

`{` が[key:関数の本体]と読まれています。`value:` はラベルとして無視されます。

丸括弧で囲むと、オブジェクトとして読まれます。

```js run
const right = (n) => ({ value: n });

console.log(right(1));
```
```output
{ value: 1 }
```

**`=> ({ ... })` はそのまま覚えてしまうのが早い**です。

## 名前を付ける

```js run
function declared() {}
const expression = function () {};
const arrow = () => {};

console.log(declared.name, expression.name, arrow.name);
```
```output
declared expression arrow
```

`const` に入れた関数にも、**変数名から名前が付きます。**
エラーの表示に出るので、名前があると原因を追いやすくなります。

```js run
const fns = { load: () => 1 };

console.log(fns.load.name);
console.log((() => {}).name);
```
```output
load

```

その場で書いた関数には名前がありません（空文字）。
[dim:2行目が空いているのは、名前が空文字だからです。]

## どれを使うか

**新しく書くならアロー関数が短くて済みます。** ただし次の場合は `function` を使ってください。

- オブジェクトの**メソッド**として書く（`this` が要る）
- 定義より前で呼びたい

```js run
const user = {
  name: 'あ',
  greet() {
    return this.name;
  },
};

console.log(user.greet());
```
```output
あ
```

アロー関数は `this` を持たないので、**メソッドには向きません。**
→ [なぜ this は呼び方で変わるのか](/ja/javascript/why/this-binding/)

## よくある間違い

### 呼ばずに関数そのものを渡す

```js bad
const double = (n) => n * 2;

console.log(double);
console.log(double + 1);
```
```output
[Function: double]
(n) => n * 21
```

`()` を付けないと、**関数そのもの**が値として扱われます。
文字列と足すと、コードがそのまま繋がります。

[bad:画面に関数の中身が出たら、`()` の付け忘れを疑ってください。]

### 引数の数が合わなくても落ちない

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

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

**多すぎても少なすぎてもエラーになりません。**
足りない分は `undefined` になり、計算に使うと `NaN` です。

既定値を書いておくと防げます。
→ [関数の引数 — 既定値・可変長・分割代入](/ja/javascript/reference/function/parameters/)

## まとめ

- 書き方は3つ。**結果は同じ**で、違うのは「前で呼べるか」と「`this`」
- `function` 宣言だけが[em:定義より前で呼べる]
- `return` が無ければ `undefined`。**エラーにはならない**
- アロー関数で `{}` を書いたら `return` が要る
- オブジェクトを返すなら `=> ({ ... })`
- 引数の数が合わなくても落ちない

## 次に学ぶ

関数の中で作った変数が[key:どこから見えるか]を学びます。
そして「関数が、作られた場所の変数を覚えている」という性質（閉包）まで進みます。

→ [第2回: スコープと閉包](/ja/javascript/learn/function/scope/)
