# private property by closure

[JS](../../..) ⟩ [value](../..) ⟩ [function](..) ⟩ [closure]() ⟩ private property by closure

{% hint style="success" %}
<mark style="color:yellow;">**hide**</mark> object [prop](../../obj/prop "mention") in a [](<> "mention").
{% endhint %}

{% tabs %}
{% tab title="👥 相關" %}
* [private-protected-members](../../class/member/private-protected-members "mention")
* [private](../../class/member/private "mention")
{% endtab %}

{% tab title="💈例一" %}
* replit：[closure: private property](https://replit.com/@pegasusroe/closure-private-property)

```javascript
'use strict';                // ⭐ toggle sloppy/strict mode

const { log } = console;

// bank account
function BankAccount(initialBalance = 0) {

    // ⭐ initial balance
    let balance = initialBalance;

    // ⭐ return an object
    return {

        getBalance() {
            return balance
        },

        deposit(amount) {
            balance += amount;
            return balance;
        },

        withdraw(amount) {

            // check if we have enough money to withdraw.
            if (amount > balance) {
                log(`❗ balance: $${balance} less than withdraw amount: $${amount}.`);
                return false;         // withdraw failed
            }

            balance -= amount;
            return true;              // withdraw successful

        }
    }
}

const myAccount = BankAccount(100);   // initial balance = 100

// log
[
    myAccount.deposit(10),     // 110
    myAccount.withdraw(80),    // true (successful)
    myAccount.getBalance(),    // 30
    
    myAccount.withdraw(80),    // false (failed)
                               // ❗ balance (30) is less then withdraw amount (80).
    
    myAccount.getBalance(),    // 39
    
].forEach(x => log(x));
```
{% endtab %}

{% tab title="💈例二" %}
* replit：[private property by closure (2)](https://replit.com/@pegasusroe/private-property-by-closure-2#index.js)

```javascript
// Counter
function Counter() {
    
    // ⭐️ private property in closure
    let count = 0;

    // ⭐️ (method) function closes over `count`
    this.up = function() {
        return ++count;
    };
    
    this.down = function() {
        return --count;
    };
}

// an instance of Counter
let counter = new Counter();

counter.up(),    // 1
counter.up(),    // 2
counter.down(),  // 1
```
{% endtab %}

{% tab title="📗 參考" %}
* [ ] Marcelo ⟩ [Closures - Private Variables and Methods in JavaScript](https://lazamar.github.io/closures-private-variables-and-methods-in-javascript/) ⭐️
* [ ] JS.info ⟩ [Closures](https://javascript.info/closure#counter-object) ⭐️
{% endtab %}
{% endtabs %}
