# class field

[JS](https://lochiwei.gitbook.io/web/js) ⟩ [class](https://lochiwei.gitbook.io/web/js/val/class) ⟩ [definition](https://lochiwei.gitbook.io/web/js/val/class/member) ⟩ class fields

{% hint style="info" %} <mark style="color:purple;">**class fields**</mark> 指寫在 [class definition](https://lochiwei.gitbook.io/web/js/val/class/member) 中，但在 <mark style="color:purple;">**`constructor()`**</mark> <mark style="color:red;">外面</mark>的 <mark style="color:orange;">**instance properties**</mark>。[據說](https://stackoverflow.com/a/57609078/5409815)這種新語法是為了改良原有的<mark style="color:purple;">**`constructor()`**</mark>語法，讓物件屬性更突出、更易於集中管理而設計的做法。
{% endhint %}

{% hint style="warning" %}
In the context of [classes](https://lochiwei.gitbook.io/web/js/val/class), <mark style="color:yellow;">MDN Web Docs</mark> content uses the terms <mark style="color:yellow;">properties</mark> and [fields](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields) <mark style="color:yellow;">interchangeably</mark>.
{% endhint %}

{% tabs %}
{% tab title="⭐️ 重點" %}
{% hint style="danger" %} <mark style="color:purple;">**class fields**</mark> are **defined** on the <mark style="color:yellow;">**instance**</mark>, <mark style="color:red;">**not**</mark> on the <mark style="color:yellow;">**prototype**</mark>.

👉 MDN ⟩ [arrow functions used as methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#arrow_functions_used_as_methods)
{% endhint %}

{% hint style="warning" %}
The <mark style="color:purple;">**class fields**</mark> are initialized:

* <mark style="color:red;">**base class**</mark>: **before** <mark style="color:purple;">**`constructor()`**</mark>
* <mark style="color:orange;">**derived class**</mark>: immediately **after** <mark style="color:purple;">**`super()`**</mark>&#x20;

👉 更詳細內容，請看： [override-class-fields](https://lochiwei.gitbook.io/web/js/val/class/inheritance/override-class-fields "mention")
{% endhint %}
{% endtab %}

{% tab title="🔴 主題" %}

* [arrow](https://lochiwei.gitbook.io/web/js/val/func/arrow "mention") used [arrow-function-as-class-field](https://lochiwei.gitbook.io/web/js/val/func/arrow/arrow-function-as-class-field "mention").
  {% endtab %}

{% tab title="📗 參考" %}

* [ ] JS.info ⟩ class ⟩
  * [ ] [class fields](https://javascript.info/class#class-fields)
  * [ ] [overriding class fields](https://javascript.info/class-inheritance#overriding-class-fields-a-tricky-note)
    {% endtab %}

{% tab title="📘 手冊" %}

* [ ] [Public class fields](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields)
  {% endtab %}

{% tab title="👥 相關" %}

* [override-class-fields](https://lochiwei.gitbook.io/web/js/val/class/inheritance/override-class-fields "mention") is kind of **tricky**, watch out❗️
* [getter-setter](https://lochiwei.gitbook.io/web/js/val/class/member/getter-setter "mention") behaves like a normal property.
* [static](https://lochiwei.gitbook.io/web/js/val/class/member/static "mention") may not be supported in all browsers.
* can be used as a [bound-method](https://lochiwei.gitbook.io/web/js/val/class/member/bound-method "mention") via [arrow](https://lochiwei.gitbook.io/web/js/val/func/arrow "mention").
* [gas](https://lochiwei.gitbook.io/web/appendix/gas "mention") 目前不支援 [field](https://lochiwei.gitbook.io/web/js/val/class/member/field "mention")，但可用 ([static](https://lochiwei.gitbook.io/web/js/val/class/member/static)/instance) [getter-setter](https://lochiwei.gitbook.io/web/js/val/class/member/getter-setter "mention") 代替。
  {% endtab %}

{% tab title="🗣 討論" %}

* [What are "class fields" in JavaScript?](https://stackoverflow.com/a/57609078/5409815)

About **Google Apps Script** Editor:

* [How to use static method in google app script](https://stackoverflow.com/questions/69202290/how-to-use-static-method-in-google-app-script)
* [How to declare Class fields in Google App Script using javascript](https://stackoverflow.com/a/72290771/5409815)
* [ParseError: Unexpected token = when trying to save in google Apps Script editor \[duplicate\]](https://stackoverflow.com/q/68446467/5409815)
* Google ⟩ Issue Tracker ⟩ [static class property not recognised](https://issuetracker.google.com/u/1/issues/194120497?pli=1) (<mark style="color:orange;">**won't fix**</mark>)
  {% endtab %}

{% tab title="❓" %}
{% hint style="danger" %}
問：「 **Google Apps Script** 目前 (2022.05) <mark style="color:red;">不支援</mark> **static members**，但是支援 **class fields** 嗎 」❓

答：「 Google Apps Script 不支援的是 [field](https://lochiwei.gitbook.io/web/js/val/class/member/field "mention")(不管是 static 還是 instance)，但神奇的是，它竟然支援 (<mark style="color:red;">**static**</mark>**/**<mark style="color:green;">**instance**</mark>) <mark style="color:orange;">**methods/getters/setters**</mark>❗️」
{% endhint %}

{% hint style="success" %}
💊 解藥：

因此，我們可以用以下方案解決 GAS 不支援 [field](https://lochiwei.gitbook.io/web/js/val/class/member/field "mention") 的問題。

* instance class fields：用 constructor 或用一般的 getters/setters。
* static class fields：用 static getters/setters，如下面的範例。
  {% endhint %}

```javascript
class X {
   // ⭐️ static getters & setters
   static get a(){ return this._a || 0 }     // this === X
   static set a(value){ this._a = value }    // this === X
}

X.a      // get: 0.0
X.a = 3  // set: 3.0
X.a      // get: 3.0
```

{% endtab %}
{% endtabs %}
