There are 2 ways to achieve Encapsulation in JS:
- Protected Properties and Methods: coding convention (not true private), use
_
before a property to notify other developer this property is protected and should not be used directly. - Private Class Fields and Methods: languague feature that is still under proposal, might not work for every browser and are subjected to syntax change.
// 1) Public fields
// 2) Private fields
// 3) Public methods
// 4) Private methods
// (there is also the static version)
class Account {
// 1) Public fields (only in the instances, not in the prototype)
locale = navigator.language;
// 2) Private fields (only in the instances, not in the prototype)
#movements = [];
#pin;
constructor(owner, currency, pin) {
this.owner = owner;
this.currency = currency;
this.#pin = pin;
// Protected property.
// this._movements = [];
// this.locale = navigator.language;
console.log(`Thanks for opening an account, ${owner}`);
}
// 3) Public methods
// Public interface
getMovements() {
return this.#movements;
}
deposit(val) {
this.#movements.push(val);
return this;
}
withdraw(val) {
this.deposit(-val);
return this;
}
requestLoan(val) {
// if (this.#approveLoan(val)) {
if (this._approveLoan(val)) {
this.deposit(val);
console.log(`Loan approved`);
return this;
}
}
static helper() {
console.log('Helper');
}
// 4) Private methods
// #approveLoan(val) { // haven't worked yet with Chrome
_approveLoan(val) {
return true;
}
}
const acc1 = new Account('Jonas', 'EUR', 1111);
// acc1._movements.push(250);
// acc1._movements.push(-140);
// acc1.approveLoan(1000);
acc1.deposit(250);
acc1.withdraw(140);
acc1.requestLoan(1000);
console.log(acc1.getMovements());
console.log(acc1);
Account.helper();
// console.log(acc1.#movements);
// console.log(acc1.#pin);
// console.log(acc1.#approveLoan(100));
// Chaining
acc1.deposit(300).deposit(500).withdraw(35).requestLoan(25000).withdraw(4000);
console.log(acc1.getMovements());