プログラミングマガジン

プログラミングを中心にIT技術をできるだけわかりやすくまとめます。

  • ホーム
  • JavaScript
  • 【JavaScript】「クロージャ」について
 
 
     
  • サーバー言語  
    • Python
    • Ruby
    • PHP
    • SQL
  •  
  • インフラ  
       
    • AWS
    •  
    • 基本
    • Git
  • Web
       
    • Web開発
    • JavaScript
    • Vue.js
    • React
  •  
  • 設計  
       
    • 実装設計
    • DB設計
  • 問い合わせ
  

【JavaScript】「クロージャ」について

07.07

  • miyabisan2
  • コメントを書く

この記事は2分で読めます

クロージャを理解するためのポイント

JavaScriptは関数の中に関数を定義できる。

JavaScript特有の構文になります。(JavaやC言語などではできない。)

1
2
3
4
5
6
7
8
function parentFunc() {
  console.log('親です。');
  function childrenFunc() {
    console.log('子供です。');
  }
}
 
parentFunc();

JavaScriptの関数は変数の中に入れて変数として持ち運べる。

この性質もできない言語はいっぱいあります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function parentFunc() {
  console.log('親です。');
  function childrenFunc() {
    console.log('子供です。');
  }
  return childrenFunc;
}
 
function reserveFunc(a) {
  a();
}
 
const child = parentFunc(); // 親です。
child(); // 子供です。
 
reserveFunc(child); // 子供です。

JavaScriptの関数は親の変数の値を使える。

JavaScriptの関数は別の関数の変数を使うことができません。しかし、関数が親子関係にある場合は親の関数の変数を使えます。(なお、親だけでなく祖父母など祖先要素は全て参照できます。:スコープチェイン)

1
2
3
4
5
6
7
8
function parentFunc() {
  const oyaValue = '親';
  console.log('親です。');
  function childrenFunc() {
    console.log(`${oyaValue}の子供です。`);
  }
  return childrenFunc;
}

JavaScriptの関数の「親」は「生みの親」のこと。

実行されたタイミングではなく、定義された場所の親を親の関数とします。これを「レキシカルスコープ」と呼びます。(なお、実行されたタイミングの関数を親とする考え方を「ダイナミックスコープ」と呼びます。JavaScriptはダイナミックスコープではないですが。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function parentFunc() {
  const oyaValue = '親';
  console.log('親です。');
  function childrenFunc() {
    console.log(`${oyaValue}の子供です。`);
  }
  return childrenFunc;
}
 
function reserveFunc(a) {
  const betujin = '別人';
  a(); // betujinという変数にはアクセスできない。
}
 
const child = parentFunc(); // 親です。
child(); // 子供です。
 
reserveFunc(child); // 子供です。

「クロージャ」とは?

一言で言えば、「親のローカル変数を参照している関数内関数のこと」で、一時記憶領域を提供し続けることができます。

通常は、ローカル変数は、関数が呼ばれ終わったら内容がクリアされます。

しかし、関数内の関数がローカル変数を参照している場合は、関数終了後も、ローカル変数の値は保持され続けます。

用途

管理しやすい変数を作るため

グローバル変数だと値がちゃんと正常か常に気を使わないとダメですが、クロージャーの変数なら気を使う必要がないです。(外側からは絶対にアクセスがされないプライベート変数になる。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let generatePerson = () => {
  let age = 0;
  return {
    getAge: () => age,
    incrementAge: () => {
      age += 1;
      console.log("age", age);
    },
  };
};
 
const person = generatePerson();
person.incrementAge();
person.incrementAge();
console.log(person.getAge());

generatePersonのincrementAgeでそのままオブジェクトを返してしまうと外側から操作できてしまいますが、関数を返せば外側からは自由に値を変更できません。

getAgeもそのままageを返すのではなく関数を返しているのが特徴です。

コールバック関数をカスタマイズしてコードをスッキリさせれる。

コールバック関数によっては決められたシグネチャしか受け付けてくれない。しかし、クロージャを使って関数を再定義してあげることによって別途条件分岐して定義することができる。

利点としては、コールバック地獄を脱出させてコードをスッキリ記述するための手段として使われる。(今までは入れ子にしまくっていたのがクロージャを使えば引数として必要なものを渡してあげれば、親の変数を使うことができるので外だしすることができるため。)

ただ、今はPromiseやasync、awaitなどの構文があるためそちらでも代替は可能。

例

定義

以下の例で言えば、「innerFunc」がクロージャになります。(通常は無名関数にすることが多いです。)

1
2
3
4
5
6
7
8
9
10
function outerFunc() {
 
    const a = 1;
 
    function innerFunc() {
        a = a + 1
    }
 
    return innerFunc();
}

呼び出し

1
2
3
4
5
var closure = outerFunc()
 
closure(); // 1
closure(); // 2
closure(); // 3

スポンサーリンク
  • 2018 07.07
  • miyabisan2
  • コメントを書く
  • JavaScript
  • Tweets Twitter
  • このエントリーをはてなブックマークに追加
  • LINEで送る

関連記事

  1. 2020 02.29

    【webpack】設定の基本や「loader(ローダー)」について

  2. 2020 04.29

    【JavaScript】「シンボル」、「イテレーター」、「ジェネレータ」について

  3. 2018 07.05

    【JavaScript】「Globalオブジェクト」について

  4. 2022 10.10

    【Prisma】sqliteで実装

  5. 2018 04.12

    【JavaScript】イベントハンドラ、イベントリスナについて

  6. 2018 07.08

    【JavaScript】「ECMAScript2015」から導入された「モジュール」について

  • コメント ( 0 )
  • トラックバック ( 0 )
  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

返信をキャンセルする。

【JavaScript】「関数リテラル(匿名関数)」、…

【Vue.js】Vue.jsの設計思想(リアクティブシ…

RETURN TOP

著者プロフィール

エンジニア歴10年で過去に業務系、Webデザイン、インフラ系なども経験あります。現在はWeb系でフロントエンド開発中心です。

詳細なプロフィールはこちら

スポンサーリンク

カテゴリー

  • Android
  • AngularJS
  • API
  • AWS
  • C++
  • CSS
  • cursor
  • C言語
  • DDD
  • DevOps
  • Django
  • Docker
  • Figma
  • Git
  • GitLab
  • GraphQL
  • gRPC
  • Hasura
  • Java
  • JavaScript
  • Kubernetes
  • Laravel
  • linux
  • MySQL
  • Next.js
  • nginx
  • Node.js
  • NoSQL
  • Nuxt.js
  • Oracle
  • PHP
  • Python
  • React
  • Redux
  • Rspec
  • Ruby
  • Ruby on Rails
  • Sass
  • Spring Framework
  • SQL
  • TypeScript
  • Unity
  • Vue.js
  • Webサービス開発
  • Webデザイン
  • Web技術
  • インフラ
  • オブジェクト指向
  • システム開発
  • セキュリティ
  • その他
  • データベース
  • デザインパターン
  • テスト
  • ネットワーク
  • プログラミング全般
  • マイクロサービス
  • マイクロソフト系技術
  • マルチメディア
  • リファクタリング
  • 副業
  • 未分類
  • 業務知識
  • 生成AI
  • 設計
  • 関数型言語
RETURN TOP

Copyright ©  プログラミングマガジン | プライバシーポリシー