privateの概要
| アクセス制御(プライベートメンバー) JavaScript予約語 | ||
|
private 概要 わかりやすく説明 |
||
|
privateの基本的な使い方
プライベートフィールドを定義する際は、識別子の先頭に # を付与します。
これは、クラスの内部からのみ参照可能なスコープを持つことを明示する記述法です。
// #記法を使用したプライベートフィールドの定義
class User {
#name; // プライベートプロパティの宣言
constructor(name) {
this.#name = name; // クラス内部のスコープからはアクセス可能
}
// 外部へ安全にデータを公開するためのゲッターメソッド
getName() {
return this.#name;
}
// 外部から安全に変数を更新するためのセッターメソッド
setName(newName) {
if (newName.length > 0) {
this.#name = newName;
}
}
}
const user = new User("Alice");
console.log(user.getName()); // 出力: Alice
// console.log(user.#name); // 🛑 構文エラー(SyntaxError): クラス外部からの直接参照は不可
- プライベートフィールドは、使用する前にクラスのトップレベルブロック内で事前に宣言しておく必要があります。
- 動的にオブジェクトへプライベートフィールドを追加したり、後から削除したりすることはできません。
privateの応用例(カプセル化による状態管理の適正化)
プライベートフィールドは、銀行口座の残高管理やシステムの設定値など、特定のビジネスロジックやバリデーション(整合性チェック)を経由せずに変更されては困るデータを保護する際に有効です。
class BankAccount {
#balance; // 外部からの直接書き換えを制限する残高データ
constructor(initialBalance) {
this.#balance = initialBalance;
}
// 金額チェックのロジックを内包した公開メソッド
deposit(amount) {
if (amount > 0) {
this.#balance += amount;
console.log(`入金処理が完了しました。現在の残高: ${this.#balance}円`);
}
}
// 読み取り専用のアクセスを提供するメソッド
getBalance() {
return this.#balance;
}
}
const account = new BankAccount(1000);
account.deposit(500);
// account.#balance = 0; // 🛑 外部から直接データを操作することは仕様上不可能です
- この設計を採用することで、オブジェクト内の状態変化はすべてクラス自身が定義したルールに依存するため、プログラム全体の強固な不変性と安全性が保たれます。
注意点
- アンダースコア(_)を用いた慣習的表現との相違: 従来のJavaScriptでは、開発者間の暗黙の了解として
_nameのように記述してプライベートを表現する手法が用いられていましたが、これは構文上の制限がないため外部からのアクセスが可能でした。
一方、#記法によるプライベートフィールドは、言語エンジンが直接アクセス制限を担保する仕組みであるため、根本的に安全性が異なります。 - サブクラス(派生クラス)への非公開性: プライベートフィールドのスコープは、それを宣言したクラス自身に限定されます。
extendsキーワードを使用して親クラスを継承した子クラスであっても、親クラスが保持する#フィールドを直接参照することはできません。
よくある質問
- Q: サブクラスから親クラスのプライベート変数を利用したい場合はどのように実装すべきですか?
- A: 親クラス側に、特定の操作を仲介する公開メソッド(ゲッターやセッター)を実装してください。
Javaにおけるprotectedのようなアクセス制御子はJavaScriptには存在しないため、カプセル化の原則に従って、適切なインターフェース経由でデータをやり取りする設計を行います。 - Q: なぜ他の言語のように
privateというキーワードを採用せず、#という記号が選ばれたのですか? - A: 既存のWebエコシステムにおける互換性(後方互換性)の維持と、実行時のパフォーマンス向上のためです。
privateを動的言語であるJavaScriptへそのまま導入しようとすると、プロパティアクセスのたびにスコープ検索などの追加コストが発生する課題がありました。記号の#を構文に組み込むことで、コードの静的解析が容易になり、実行前にアクセス権の妥当性を高速にチェックできるメリットが生まれます。
まとめ
privateなプライベートフィールド(#記法)は、大規模開発においてコンポーネント間の依存関係を整理し、安全なデータカプセル化を行うための基盤仕様です。
- 意図しない外部からの変更を遮断すべきオブジェクトの内部変数には
#を適用し、情報の隠蔽を徹底してください。 - 単なる命名規則であるアンダースコア(
_)から言語仕様の#記法へ移行することで、より厳密なカプセル化が実現します。 - 公開メソッドを最小限に絞り込み、内部のデータ構造やロジックを隠蔽することで、クラスの変更が他のプログラムに影響を与えにくい疎結合なソフトウェア設計を心がけましょう。