icon
icon

JavaScriptのクロージャの使い方を現役エンジニアが解説【初心者向け】

初心者向けにJavaScriptのクロージャの使い方について現役エンジニアが解説しています。クロージャとは関数とその関数を作った場所をまとめたものです。クラスと同じように変数のスコープを切って、独自に扱うことが出来ます。実際にサンプルプログラムでクロージャを作成してみましょう。

テックアカデミーマガジンは受講者数No.1のプログラミングスクール「テックアカデミー」が運営。初心者向けにプロが解説した記事を公開中。現役エンジニアの方はこちらをご覧ください。 ※ アンケートモニター提供元:GMOリサーチ株式会社 調査期間:2021年8月12日~8月16日  調査対象:2020年8月以降にプログラミングスクールを受講した18~80歳の男女1,000名  調査手法:インターネット調査

監修してくれたメンター

永井浩平

BtoBtoC事業を行っている会社で社内SEとして勤務。
バックエンド、フロント、クラウドなど幅広く業務を行う。
テックアカデミーでは、フロントエンドコース / Javaコースのメンター。

JavaScriptのクロージャの使い方について、テックアカデミーのメンター(現役エンジニア)が実際のコードを使用して初心者向けに解説します。

目次

1時間でできる無料体験!

そもそもJavaScriptについてよく分からないという方は、JavaScriptとは何なのかについて解説した記事を読むとさらに理解が深まります。

 

田島悠介

今回は、JavaScriptに関する内容だね!

大石ゆかり

どういう内容でしょうか?

田島悠介

JavaScriptのクロージャの使い方について詳しく説明していくね!

大石ゆかり

お願いします!

 

はじめに

JavaScirptのクロージャとスコープに関して説明します。

大規模なアプリなどの実装をする際には、複数画面で共通する処理を1つのJavaScriptファイルにまとめることがあります。

複数の処理から変数や関数が呼ばれた際に、今回説明するクロージャやスコープなどが適切に考慮されていない場合、共通変数の値などが前の処理で書き換わって、思わぬ動作不良などを起こす原因となります。

大規模なアプリやプロジェクトでは必要な知識ですので、ぜひ理解して少しずつ日々のコーディングで意識してみてくださいね。

 

グローバルスコープ

グローバルスコープとは、JavaScriptのどこからでもアクセスできる範囲を指します。

 

以下の例ではnameとbirthPlaceがグローバル変数です。

let name  = "";
let birthPlace = "";
const introduce =() =>{
    console.log("名前は" + name + ":出身地は" + birthPlace );
};

 

「名前は田中:出身地は東京」とログに出力したい場合は、以下のように変数に代入してintroduceを呼べば目的の文字列を出力できます。

name = "田中";
birthPlace ="東京";
introduce();     //console => 名前は田中:出身地は東京

上記のように、グローバルスコープはどこからでも参照できるのでとても便利ですが、他の処理からbirthPlaceを変更された場合、「名前は田中:出身地は山梨」というように、誤った結果を出力してしまう可能性があります。

 

以下、外部のAPIからデータを取得する例です。

let globalJsonData;
const getApiData1 = () => {
     //API通信の処理
     fetch('https://XXXXXXXXXXX')
     .then(response => response.json())
     .then( jsonData => globalJsonData =jsonData );
}
const getApiData2 = () => {
     //API通信の処理
     fetch('https://ZZZZZZZZZZZ')
     .then(response => response.json())
     .then( jsonData => globalJsonData =jsonData );
}

getApiData1();
getApiData2();
windows.onload = function(){
    console.log(globalJsonData);  //getApiData1 ,getApiData2 で取得したどちらかのデータが出力
}

非同期通信ですので、getApiData1とgetApiData2、それぞれのAPIの取得のレスポンスの遅い方が、最終的にglobalJsonDataに保持されます。

そのため、ソース上の処理順序としてはgetApiData2の結果が格納されているはずですが、getApiData1の結果となる場合もあります。

 

非同期処理や複数の処理から更新される可能性のあるデータなどは管理が難しくなるため、グローバルスコープで宣言する際には注意が必要です。

globalJsonDataの例では、globalJsonData1,globalJsonData2のように個別に変数を宣言すれば問題ないのですが、nameやbirthPlaceなどの例では人数に比例してどんどん変数が増えていき、現実的ではありません。

そこでクロージャやローカルスコープなどを利用することで、変数やオブジェクトの参照範囲を限定し、誤った参照や更新を防ぐことができます。

 

[PR] フロントエンドで副業する学習方法を動画で公開中

クロージャとは

クロージャとは、関数とその関数を作った場所をまとめたものです。

同じ変数をオブジェクトごとに安全に使いまわすことができ、ソース量も減らせます。

 

以下の例を見てみましょう。

let makeHuman = function (parName,parBirthPlace){
    let name = parName;
    let birthPlace =parBirthPlace;
    return {
        introduce:function(a){ console.log("名前は" + name +":出身地は" + birthPlace );},
    }
}
const tanaka = makeHuman('田中','東京');
tanaka.introduce();//①console => 名前は田中:出身地は東京

const yoshida = makeHuman('吉田','山梨');
yoshida.introduce();//②console => 名前は吉田:出身地は山梨

tanaka.introduce();//③console => 名前は田中:出身地は東京

console.log(birthPlace);//× makeHumanオブジェクトのプロパティ「birthPlace」は直接参照出来ないためエラー
                        //Uncaught ReferenceError: birthPlace is not defined

「makeHuman」というオブジェクトには、name,birthPlaceの2つの変数とintroduceという1つの関数が定義されています。

makeHuman(‘名前’,’出身地’);を呼び出しtanakaというオブジェクトに格納しました。

このtanakaがクロージャです。

tanakaのnameはtanakaというオブジェクト内でのみ参照できるので、yoshidaというオブジェクトを宣言しても、tanakaのnameやbirthPlaceは影響を受けません。

また17行目の記載で、makeHumanオブジェクトのbirthPlaceというプロパティを直接参照することもできないのでエラーとなります。

ECサイトの買い物かごなどの情報を一時的にJavaScriptで処理する際には、商品情報などを上記のようなオブジェクトごとに持たせて配列などで管理できます。

 

コラム

コスパとタイパ、両方結果的に良くなる良くなる学び方とは?

「スクールは高いし時間も縛られて効率が悪い」と考える方は多いと思います。
もちろん、時間も費用もかかることは間違いありません。
ただ 結果的に無駄な学びにお金も時間もかける方がリスクが高いという考えもあります。

コスパ・タイパ最適化の参考として、 テックアカデミー卒業生がスクールを選んだ理由 をご紹介します。

  • ・困ったときに、質問や相談できる相手がいるため挫折しなかった
  • ・プロとして必要なスキルのみを深く学べたので無駄がなかった
  • ・副業案件の提供と納品までのサポートがあったので目的を達成できた

安価・短期間で広く浅く学んでも意味がありません。 本当に自分の目的が達成できるか、それが重要です。
自分にどのスキルや学び方が合っているか、どんな学習方法かなど、お気軽に 無料相談 に参加してみませんか?

カウンセラー・現役のプロへ、何でも気軽に無料相談可能。 30分か60分お好きな時間が選べて、かつ3回まで すべて無料で ご利用できます。
無理な勧誘は一切ない ので、お気軽にご参加ください。

今なら相談した方限定の割引・参加特典付き! 無料相談はこちら

ローカルスコープとは

グローバルスコープの対となるローカルスコープは参照範囲を限定できます。

また、種類は以下の2つありますので覚えておきましょう。

 

1、関数スコープ

以下の例のように、関数の{}で区切られた範囲を指します。

グローバル変数と違い、関数が別であれば同じ変数名も宣言できます。

const getName = () => {
  let element = document.getElementById('name');
  return element.value;
};

const getBirthPlace = () => {
  let element = document.getElementById('birthPlace');
  return element.value;
};
console.log(getName());        //console => nameに入力された値を出力
console.log(getBirthPlace());  //console => birthPlaceに入力された値を出力
console.log(element);// ×関数スコープ内のオブジェクトを直接参照出来ないためエラー
                     //Uncaught ReferenceError: birthPlace is not defined

 

2、ブロックスコープ

ブロックスコープは{}に囲まれた中だけ有効となります。

以下の例では、1つめのconsole.logでは同一の{}内なのでnameを参照できますが、2つめのconsole.logでは{}の外なのでnameを参照できません。

{
    let name = "田中";
    console.log(name);//console => 田中
}
console.log(name);// ×ブロックスコープ内のオブジェクトを直接参照出来ないためエラー
                     //Uncaught ReferenceError: birthPlace is not defined

 

クロージャでは、関数スコープを利用します。

関数の中で作られた変数や処理は、関数の中でしかアクセスできないということを覚えておいてください。

 

クロージャを使うメリット

関数スコープを使い、変数や処理を閉じ込めて専用にするクロージャのメリットは、グローバルスコープのところで簡単に触れましたが、大きく下記2点です。

・他の処理などから値の参照・変更を不可にできる。

・変数など使いまわしができる。

特に2つめのメリットはとても便利です。

今回は名前と出身地だけでしたが、その他にも血液型、性別、身長、体重など、いろいろな情報を保持する際に、安全に内包された変数に値を保持することができます。

そのため、大規模なアプリ開発や複数人での開発などでは必須の知識ですので、この機会に覚えて、ぜひ使ってみてくださいね。

大石ゆかり

内容が分かりやすくて良かったです!

田島悠介

ゆかりちゃんも分からないことがあったら質問してね!

大石ゆかり

分かりました。ありがとうございます!

 

1時間でできる無料体験!

JavaScriptを学習中の方へ

これで解説は終了です、お疲れさまでした。

  • つまずかず「効率的に」学びたい
  • 副業や転職後の「現場で使える」知識やスキルを身につけたい

プログラミングを学習していて、このように思ったことはありませんか?

テックアカデミーのフロントエンドコースでは、第一線で活躍する「プロのエンジニア」が教えているので、効率的に実践的なスキルを完全オンラインでしっかり習得できます。

合格率10%の選考を通過した、選ばれたエンジニアの手厚いサポートを受けながら、JavaScript・jQueryを使ったWebサービス開発を学べます。

まずは一度、無料体験で学習の悩みや今後のキャリアについて話してみて、「現役エンジニアから教わること」を実感してみてください。

時間がない方、深く知ってから体験してみたい方は、今スグ見られる説明動画から先に視聴することをおすすめします!

初心者・未経験でもできる。まずはテックアカデミーに相談しよう

プログラミングを独学で学習していて、このように感じた経験はないでしょうか?

  • ・調べてもほしい情報が見つからない
  • ・独学のスキルが実際の業務で通用するのか不安
  • ・目標への学習プランがわからず、迷子になりそう

テックアカデミーでは、このような 学習に不安を抱えている方へ、マンツーマンで相談できる機会を無料で提供 しています。
30分間、オンラインでどんなことでも質問し放題です。

「受けてよかった」と感じていただけるよう カウンセラーやエンジニア・デザイナー があなたの相談に真摯に向き合います。

「自分に合っているか診断してほしい」
「漠然としているが話を聞いてみたい」

こんなささいな悩みでも大丈夫です。

無理な勧誘は一切ありません ので、まずはお気軽にご参加ください。
※体験用のカリキュラムも無料で配布いたします。(1週間限定)

今なら参加者限定の割引特典付き! 無料相談を予約する