JavaScriptのカプセル化に関わるパブリッククラスフィールド

2021年3月11日JavaScript

JavaScriptのカプセル化に関わる、パブリッククラスフィールドについて基礎的な部分をまとめました。
まだ、ステージ3のため、ブラウザの対応状況次第で使えなくなることもあります。

パブリッククラスフィールドの8つのフィールド

パブリックフィールド Public fields
プライベートフィールド Private fields
パブリックメソッド Public methods
プライベートメソッド Private methods
これらと、staticの同じものが4つあります。
よく使うと思われる上の4つの使い方をみていきましょう。

パブリッククラスフィールドの例


class Account {
// Public fields(instances)
//引数をとらないただのプロパティをかくところ
//これらはプロトタイプには含まれない。これらはインスタンスに含まれる
locale = navigator.language;

// パブリックフィールド (instances)
//カプセル化でとても大事なのがこのプライベートフィールド。
//外部からアクセスできないようにできる。
// _movements = [];
// _ではまだ呼び出すときに_をつければアクセスできていましたが、#にするとアクセスできなくなります。
#movements = [];
//続いてpasswordもここに入れたいけれども、constructorの中のpasswordを受け取っているのでできません。
//そこで、このフィールドで#をつけて空の宣言をします。
#password;

  constructor(owner, currency, password) {
    this.owner = owner;
    this.currency = currency;
    // _をつけることで守られる、本来のやり方ではない。なぜならacc1._movements.push()とすれば同じく操作できるから。他の開発者が賛成したら使ってもいいけど。
    // this._password = password;
    this.#password = password;
    // this._movements = [];
    // this.locale = navigator.language;

    console.log(`ありがとう、${owner}`);
  }

  // パブリックメソッドはいままで使っていたやり方と同じ
  // Public interface
  //こうすることで、見ることはできるけど変えることはできなくなる。
  getMovements() {
    // return this._movements;
    return this.#movements;
  }
  deposit(val) {
    // this._movements.push(val);
    this.#movements.push(val);
  }

  withdraw(val) {
    this.deposit(-val);
  }

  
  requestLoan(val) {
    if(this._approveLoan(val)) {
      this.deposit(val);
      console.log('承認されました。');
    }
  }
  
  // プライベートメソッド
  // #approveLoan(val) {
  //   return true;//本当はここに条件を書く
  // }
  _approveLoan(val) {
    return true;//本当はここに条件を書く
  }
  
}

const acc1 = new Account('山田', 'JPY', 5000);
console.log(acc1);


// #movementsにはアクセスできない
// console.log(acc1.#movements);//Uncaught SyntaxError: Private field '#movements' must be declared in an enclosing class
// console.log(acc1.movements);//undefinedになる
//アクセスするためには、確認専用のgetMovements()を使う。
console.log(acc1.getMovements()); 
//[]
// 0: 500
// 1: -5600
// 2: 5600

acc1.deposit(500);
acc1.withdraw(5600);
acc1.requestLoan(5600);
console.log(acc1.getMovements());

console.log(acc1);
// console.log(acc1.password);
// console.log(acc1.#password);//Uncaught SyntaxError: Private field '#password' must be declared in an enclosing class
// console.log(acc1._approveLoan);//Uncaught SyntaxError: Private field '#approveLoan' must be declared in an enclosing class

すべてのフィールドで、宣言するときに#ハッシュを使います。
パブリックフィールドとプライベートフィールドは、constructorの外、クラスの中のフィールドです。
どちらもconstructorの外のため、constructorの引数をとることはできません。
パブリックフィールドはlocaleが例になります。constructorの引数が必要ないものをここに記述します。
プライベートフィールドは、passwordが例になります。passwordは実際constructorの引数を受け取る必要があるので、空で宣言するやり方となります。

パブリックメソッドについては、今まで通りと同じやり方のことです。
getMovements()を表示することで、確認だけはすることができます。
プライベートメソッドは現在でもまだサポートが済んでいないため、使えません。
基本的には#をつけるだけで、外部からアクセスできないようになる予定です。
それまでは、_アンダースコアなどで対応する必要があります。