プライベートフィールド外部アクセスの構文エラー原因
#で始まるプライベートフィールドを、宣言したクラスの外からドットで直接読み書きしようとしたときに出るエラーです。他のエラーと違い、実行前の構文解析の段階で検出されます。
エラーメッセージの読み方
main.js:6
main.js- ファイル名
6- 行番号 — Node.jsが構文解析を諦めた位置
SyntaxError- エラークラス — 実行前の構文チェックで検出されました
Private field '#balance' must be declared in an enclosing class- 内容 — 期待していたもの、または受け付けられなかったもの
このエラーが出る典型パターン
パターン1
1 class Account { 2 #balance = 100; 3 getBalance() { return this.#balance; } 4 } 5 const acc = new Account(); 6 console.log(acc.#balance ); ^
main.js:6
console.log(acc.#balance);
^
SyntaxError: Private field '#balance' must be declared in an enclosing class
プライベートフィールドはクラスの外から直接アクセスできません。値を取得したい場合はgetBalance()のような公開メソッド経由にします。
直し方: acc.#balance を acc.getBalance() にします。
広告
広告スロット(未設定)
パターン2
1 class Wallet { 2 #balance = 500; 3 deposit(amount) { this.#balance += amount; } 4 getBalance() { return this.#balance; } 5 } 6 const w = new Wallet(); 7 w.deposit(100); 8 console.log(w.#balance ); ^
main.js:8
console.log(w.#balance);
^
SyntaxError: Private field '#balance' must be declared in an enclosing class
#balanceは宣言したクラスの中でしか読み書きできません。外部への公開はメソッドを介して行います。
直し方: w.#balance を w.getBalance() にします。
パターン3
1 class Timer { 2 #seconds = 0; 3 tick() { this.#seconds++; } 4 getSeconds() { return this.#seconds; } 5 } 6 const t = new Timer(); 7 t.tick(); 8 t.tick(); 9 console.log(t.#seconds ); ^
main.js:9
console.log(t.#seconds);
^
SyntaxError: Private field '#seconds' must be declared in an enclosing class
#secondsを外から直接読もうとすると実行前の構文チェックで弾かれます。公開したい値はgetSeconds()のようなメソッドで返します。
直し方: t.#seconds を t.getSeconds() にします。
よくある誤解
プライベートフィールドへのアクセス制限は、実行時にチェックされる通常のエラー(TypeErrorなど)だと思われがちですが、実際には構文としてその場に存在してはいけないものとして扱われ、SyntaxErrorになります。クラスの外に公開したい値は、getterやメソッド経由で提供する必要があります。
まとめ
プライベートフィールド外部アクセスの構文エラー原因は上級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。