JavaScriptのプロパティディスクリプタは、プロパティ1つ1つに対して変更や列挙、削除の可否を指定できる仕組みである。仕様では、プロパティの属性("attribute")と表現されている。
わかりやすく言えば、プロパティの設定を行うオブジェクトだ。
種類
プロパティディスクリプタには、データプロパティとアクセサプロパティの2種類がある。
指定できるのはいずれか一方のみで、両方指定しようとすると型エラーが投げられる。注意したい。
データプロパティ
データプロパティは、プロパティの「値」に関する設定を担う。以下の4つの種類がある。
なお、[[xxx]]みたいなやつはオブジェクトの内部プロパティを示す仕様上の記法である。概念を示すためのものなので、obj.[[xxx]]のようにしても内部プロパティにはアクセスできない。内部プロパティの設定には、後述するObject.defineProperty()メソッドやObject.defineProperties()メソッド、取得にはObject.getOwnPropertyDescriptor()やObject.getOwnPropertyDescriptors()を使う。
| 内部プロパティ | 概要 |
|---|---|
[[Value]] |
プロパティの値。 |
[[Writable]] |
プロパティの値を変えられるかどうかを指定するフラグ。 |
[[Configurable]] |
プロパティの削除や属性(ディスクリプタの内容)を変えられるかどうかを指定するフラグ。[[Writable]]がtrueの場合、このフラグがfalseでもプロパティの値を変更できる。 |
[[Enumerable]] |
プロパティをfor...inあるいはObject.keys()を使ったループでイテレートできるかどうかを指定するフラグ。 |
アクセサディスクリプタ
アクセサディスクリプタは、要はclass構文でお馴染みのゲッターとセッターである。プロパティが参照されたり、代入されたりする際に実行する関数オブジェクトを指定する。
| 内部プロパティ | 概要 |
|---|---|
[[Get]] |
プロパティが参照される際に実行する関数オブジェクトを指定する。 |
[[Set]] |
プロパティに値が代入される際に実行する関数オブジェクトを指定する。 |
[[Configurable]] |
同じなので割愛。 |
[[Enumerable]] |
同じなので割愛。 |
設定方法
プロパティディスクリプタの設定は、Object.defineProperty()メソッドあるいはObject.defineProperties()メソッドを使って行う。以下、データプロパティのフラグをぜんぶfalseにした例である。
1を代入してもpropの値が変化せず、またfor...inは回らず、deleteでも削除されていないことがわかる。
なお、strictモードでは、書き込もうとしたり、削除しようとしたタイミングで型エラーが出て処理が停止する。
取得方法
プロパティのディスクリプタを取得したい場合には、Object.getOwnPropertyDescriptor()あるいはObject.getOwnPropertyDescriptors() – JavaScript | MDNを使う。