2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

関数宣言・関数式・アロー関数の違いを言語化する:JavaScript関数設計の正しい選定軸

Posted at

概要

JavaScriptでは、同じ“関数”であっても
記述方法によって挙動・スコープ・バインディング・実行タイミングが大きく異なる。

  • function foo() {}
  • const foo = function() {}
  • const foo = () => {}

それぞれの選定を「なんとなく」で済ませていると、thisのバグ、タイミングのズレ、コードの責務の曖昧さが生まれる。
この記事では、関数の3つの記法を構造的に比較し、使い分けるための判断基準を明確にする。


対象環境

ES5〜ES2023対応のJavaScript(Node.js / ブラウザ)

3つの記法とその特徴

書き方 名前 this束縛 ホイスティング 再定義 用途
function foo() {} 関数宣言 動的 ✅ あり ✅ 可能 汎用 / ライブラリなど
const foo = function() {} 無名関数式 動的 ❌ なし ❌ 不可 コールバック / スコープ内関数
const foo = () => {} アロー関数 静的 ❌ なし ❌ 不可 thisが要らない関数 / 簡潔な処理

1. 関数宣言

function greet(name) {
  return `Hello, ${name}`;
}

✅ 特徴

  • ホイスティングされる → ファイル先頭で定義してなくても使用可能
  • ✅ 名前が明示される → デバッグで追いやすい
  • this は呼び出し元に依存する(動的)

2. 関数式

const greet = function(name) {
  return `Hello, ${name}`;
};

✅ 特徴

  • ❌ ホイスティングされない
  • ✅ 変数スコープ内に閉じることができる
  • this は関数宣言と同じく動的(ただし限定されやすい)

→ コールバックや関数を値として扱いたいときに便利


3. アロー関数

const greet = (name) => `Hello, ${name}`;

✅ 特徴

  • this外側のスコープからレキシカルに継承する
  • ✅ 簡潔な記法で使い捨てに最適
  • arguments が使えない
  • ❌ コンストラクタとして使えない(new不可)

DOM操作やイベントハンドラでのthisトラブルを避けるための強力なツール


thisに関する設計の分岐点

✅ 通常関数でのthis

const obj = {
  name: 'toto',
  greet: function () {
    console.log(this.name); // 'toto'
  }
};

❌ アロー関数では this は外側に束縛される

const obj = {
  name: 'toto',
  greet: () => {
    console.log(this.name); // undefined
  }
};

ホイスティングと関数式の違い

greet(); // ✅ OK(関数宣言)
function greet() {
  console.log('Hello');
}

greet2(); // ❌ ReferenceError(関数式)
const greet2 = function () {
  console.log('Hello');
};

実務的な選定指針

使用目的 推奨構文 理由
グローバルに公開する関数 関数宣言 ホイスティング + 名前が明示的
thisが関係するオブジェクトメソッド 関数式(function) thisが動的でもスコープが明確
短く簡潔な処理 / コールバック アロー関数 thisが不要 + 可読性高
コンストラクタ関数 関数宣言 アロー関数では new が使えない
イベントハンドラ(内部で this 使用) アロー関数 DOM外の this に束縛しないため

よくある誤用

❌ アロー関数でコンストラクタ

const User = (name) => {
  this.name = name;
};
const u = new User('toto'); // ❌ TypeError

→ ✅ 通常の関数で書くべき


❌ thisを使いたいのにアロー関数

const obj = {
  name: 'toto',
  init: () => {
    console.log(this.name); // ❌ undefined
  }
};

→ ✅ function() で書く必要がある


結語

関数を選ぶということは、構文を選ぶのではなく、責任の持ち方を選ぶということ。

  • this を持たせるか
  • スコープに閉じ込めるか
  • 再定義やホイスティングを許容するか

構文は表層、設計は本質。
どの関数記法を選ぶかで、コードの性格は180度変わる

JavaScript関数は「どう書くか」ではなく、「どう使われるか」で設計すべきである。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?