JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

JavaScriptのクロージャを使ってプライベートプロパティを実装する方法


JavaScriptには、Javaなどの言語のような private 修飾子が存在しないため、オブジェクトの外部からアクセスできない「プライベートな」データを表現するにはひと工夫が必要です。その定番テクニックのひとつが、クロージャ(closure) を活用する方法です。

クロージャでプライベート化が実現できる理由

クロージャとは、関数が生成された際のスコープ(外側の関数内の変数)への参照を保持し続ける仕組みのことです。関数内で宣言されたローカル変数は、外部のコードから直接参照したり書き換えたりすることはできません。

そこで、内部変数へアクセスできる関数だけを戻り値として返すようにすることで、その変数を実質的な「プライベートプロパティ」として扱えるようになります。

動作のポイント

  • 変数 atest() 関数のローカルスコープに存在するため、外部から直接アクセスできません。
  • 返却される incrementA() がクロージャとして a への参照を保持します。
  • storeVal() を呼び出すたびに a の値が1ずつ増加し、その結果が返されます。

サンプルコード

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
   body {
      font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
   }
   .result {
      font-size: 20px;
      font-weight: 500;
      color: blueviolet;
   }
</style>
</head>
<body>
<h1>クロージャによるプライベートプロパティ</h1>
<div class="result">0</div>
<br />
<button class="Btn">ここをクリック</button>
<h3>上のボタンをクリックすると、クロージャによってカウンタが増加します</h3>
<script>
   let BtnEle = document.querySelector(".Btn");
   let resEle = document.querySelector(".result");
   function test() {
      let a = 0;
      return function incrementA() {
         a++;
         return a;
      };
   }
   let storeVal = test();
   BtnEle.addEventListener("click", (event) => {
      resEle.innerHTML = storeVal();
   });
</script>
</body>
</html>

実行結果

JavaScriptのクロージャを使ってプライベートプロパティを実装する方法

ページを開くと、初期値「0」が表示されたカウンタと「ここをクリック」ボタンが配置されています。

JavaScriptのクロージャを使ってプライベートプロパティを実装する方法

ボタンをクリックするたびに、カウンタの値が1ずつ増加していきます。これは、クロージャが変数 a の状態を保持し続けているためです。

補足:モダンな代替手段

近年のJavaScriptでは、クラス構文におけるプライベートフィールド(#fieldName)も利用可能になっています。ただし、古いブラウザ環境との互換性を保ちたい場合や、関数ベースで状態をカプセル化したい場合には、クロージャによるこの手法が今でも有効です。

  1. JavaScriptでプロパティを共有する方法 ― prototype活用のコード例と解説

    JavaScriptでは、オブジェクトのprototypeプロパティに値を追加することで、プロパティを複数のインスタンス間で共有できます。prototypeに登録されたプロパティは、そのコンストラクタから生成されたすべてのインスタンスから共通して参照されます。 この手法には大きなメリットがあります。各インスタンスごとに同じ値のプロパティを個別に定義する必要がないため、コードの重複を減らし、メモリの使用量も抑えられるのです。たとえば、学校名のように全生徒で共通する情報は、prototypeにまとめておくのが理想的です。 実装例:prototypeでプロパティを共有するコード 以下は、JavaS

  2. JavaScriptで親要素にCSSクラスを適用・継承する方法をわかりやすく解説

    JavaScriptを使って新しく作成した要素にCSSのスタイル(クラス)を適用したい場合、document.createElement()、classList.add()、そしてappend()を組み合わせることで簡単に実現できます。 基本的な仕組み 処理の流れは以下の3ステップです。 1. document.createElement(): 新しいdiv要素などのHTML要素を動的に生成します。 2. classList.add(): 生成した要素に対して、あらかじめ定義しておいたCSSクラス(.classセレクタ)を追加します。これにより、そのクラスに設定されたスタイルが継承・適用されま