# private member

[JS](https://lochiwei.gitbook.io/web/js) ⟩ [value](https://lochiwei.gitbook.io/web/js/val) ⟩ [object](https://lochiwei.gitbook.io/web/js/val/obj) ⟩ [class](https://lochiwei.gitbook.io/web/js/val/class) ⟩ [member](https://lochiwei.gitbook.io/web/js/val/class/member) ⟩ private

{% hint style="success" %}

* <mark style="color:purple;">**private members**</mark> are <mark style="color:red;">**not**</mark>**&#x20;**<mark style="color:yellow;">**inherited**</mark>:exclamation:

```javascript
class A {
  // ⭐️ private members     // # means "private"
  #a;                       // this.#a = undefined
  #b = 0;                   // this.#b = 0
  get #c() { return 0 }     // this.#c   (private getter)
  #d() { ... }              // this.#d() (private method)
  
  // ⭐️ private static members
  // (accessable only within the class body)
  static #staticProp;                // A.#staticProp
  static get #CONST() { return 0 }   // A.#CONST
  static #staticMethod() { ... }  // A.#staticMethod()
}
```

{% endhint %}

{% tabs %}
{% tab title="🧨" %}
{% hint style="danger" %}

* <mark style="color:red;">**never**</mark> use "<mark style="color:purple;">**this**</mark>" to access a <mark style="color:yellow;">**private**</mark>**&#x20;**<mark style="color:orange;">**static**</mark>**&#x20;**<mark style="color:yellow;">**field**</mark>,&#x20;
* <mark style="color:red;">**always**</mark> use the <mark style="color:yellow;">**direct class name**</mark>. &#x20;

👉 📗 2ality.com ⟩ [ECMAScript proposal: private class fields](https://2ality.com/2019/07/private-class-fields.html)
{% endhint %}
{% endtab %}

{% tab title="👥" %}

* :bulb:[private-prop](https://lochiwei.gitbook.io/web/js/val/func/closure/private-prop "mention")
* [private-protected-members](https://lochiwei.gitbook.io/web/js/val/class/member/private-protected-members "mention") (duplicate?)
  {% endtab %}

{% tab title="💈" %}

```javascript
const {log} = console;

class A {

  // ⭐️ `#` is part of the name❗️

  // ⭐️ private instance members
  #age;                               // declaration only
  #n = 3;                             // with definition
  
  // const #constant = 6;             // no private constant❓
  // this.#constant2
  get #constant2() { return 2; }      // workaround
  
  #steal(something) {  }
  
  // ⭐️ private static members
  //   -----------------------
  // ⭐️ only the class which defines the private static field
  //    can access the field.
  static #TOP_SECRET;
  static #total() { return 10 }
  
  // A.constant
  static get #constant(){ return 6; }   // static constant
  
  // init
  constructor() {
    this.#age = 42;
    log(`n = ${this.#n}, total: ${A.#total()}`);
    log(`static A.constant: ${A.#constant}`);
    log(`instance constant: ${this.#constant2}`);
  }

  // this.age
  get age(){ return this.#age }
  
}// end: class A


// test run
let a = new A();            // "n = 3, total: 10"
                            // "A.constant: 6"
                            // "instance constant: 2"

log(a.age);                 // 42
```

{% endtab %}

{% tab title="✨" %}

* [make-iterables](https://lochiwei.gitbook.io/web/js/iteration/iterable/make-iterables "mention") ⟩ [💈例一](https://lochiwei.gitbook.io/web/iteration/iterable/make-iterables#li-yi)
  {% endtab %}

{% tab title="📗" %}

* [ ] JS.info ⟩ [Private and protected properties and methods](https://javascript.info/private-protected-properties-methods)
* [ ] 2ality.com ⟩ [ECMAScript proposal: private class fields](https://2ality.com/2019/07/private-class-fields.html)
* [ ] Can I use ? ⟩ [Class private fields](https://caniuse.com/?search=private%20class)
  {% endtab %}

{% tab title="📘" %}

* MDN ⟩&#x20;
  * Classes ⟩ [Private class features](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields) ⭐️
  * Guides ⟩ [Working with private class features](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_With_Private_Class_Features)
  * Web Workers ⟩ [console.assert()](https://developer.mozilla.org/en-US/docs/Web/API/console/assert)
  * console ⟩ [Outputting text to the console](https://developer.mozilla.org/en-US/docs/Web/API/console#outputting_text_to_the_console)
* GitHub ⟩ [tc39](https://github.com/tc39)/[**proposal-destructuring-private**](https://github.com/tc39/proposal-destructuring-private) **⭐️**
* TC39 (spec) ⟩  [destructuring private fields](https://tc39.es/proposal-destructuring-private/) (stage 2 draft, as of 2022/03/18)
* Node.js ⟩ [`assert.throws(fn[, error][, message])`](https://nodejs.org/api/assert.html#assert_assert_throws_fn_error_message)
  {% endtab %}

{% tab title="🗣" %}

* [Declaring static constants in ES6 classes?](https://stackoverflow.com/questions/32647215/declaring-static-constants-in-es6-classes)
* TC39 ⟩ [Destructuring instances with private fields](https://github.com/tc39/proposal-class-fields/issues/4)
  {% endtab %}

{% tab title="❓" %}
{% hint style="warning" %} <mark style="color:yellow;">**destructuring private members**</mark> not supported currently❓&#x20;

([stage 2 draft](https://tc39.es/proposal-destructuring-private/), as of 2022/03/18)

```javascript
const {#prop: prop} = this;
//     ^^^^^ (⛔ SyntaxError: Unexpected identifier)
```

{% endhint %}
{% endtab %}
{% endtabs %}

## supporting environments <a href="#evironments" id="evironments"></a>

{% tabs %}
{% tab title="✅" %}

* [x] replit
* [x] CodePen
* [ ] CodeSandbox (needs setup)
  {% endtab %}

{% tab title="CodeSandbox" %}

```javascript
// 📁 .babelrc
{
  "presets": [
    "env"
  ],
  "plugins": [
    "transform-runtime",
    "@babel/plugin-proposal-class-properties", // ╮ ⭐️ 加這兩個
    "@babel/plugin-proposal-private-methods"   // ╯
  ],
  "parserOpts": {
    "plugins": [
      "dynamicImport"
    ]
  }
}
```

{% endtab %}
{% endtabs %}
