7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Javascriptのgetter setterメモ

Posted at

getter/setterとは

以下のようにオブジェクトのpropertyにget/setを付けることにより、
プロパティの呼び出し時やプロパティへの値の代入時に関数が呼び出されるようになる。
正確には、getあるいはsetを付けるとpropetyの記述子が特別な「アクセサー記述子」になる。
(通常のpropertyはデータ記述子)

const hoge ={
 get hoge(){
    return "hoge";
 }
 set hoge(h) {
   console.log(h);
 }
}

hoge.hoge//hoge
hoge.hoge = "fuga"//consoleにfugaと出る

クロージャと組み合わせてオブジェクトのカプセル化やWrapperオブジェクトの作成に使える。

getterの挙動

getterの挙動は一見、通常のデータ記述子に対するアクセスするのと変わらない。
オブジェクト宣言中でgetterを定義した場合、通常アクセスの外、
スプレッド構文やfor...inループにも表れる。

getter、setter内で同名プロパティにアクセスした場合

getterやsetterはJavaなどの言語におけるgetterやsetterと異なり、
そのプロパティに紐づくもの自体をアクセサーに変える。
よって下記のようなコードは無限ループを引き起こす

get hoge(){
  return this.hoge;
}

getterやsetterを片方しか定義しなかった場合の挙動

getterしかないpropertyに値を代入しようとした場合には何も起こらない。
(そのプロパティが通常のデータ記述子型プロパティに変わったりはしない)
同様にsetterしかないプロパティに対して値を読みだそうとするとundefinedになる。

getterかsetterを一つでも定義した時点で、そのpropertyはアクセサー型のpropertyになるので、
未定義の側もデータ記述子型のように扱うことは出来ない。

消したい場合、更新したい場合

  • deleteを用いればpropertyごと消えるので、getter/setter共に消滅する deleteにはpropertyの種類がデータ記述かアクセサー記述かは関係ない
  • 上書きしたい場合はObject.definePropertyあるいはObject.definePropertiesを利用する。
  • 上記のdefineProperty系はプロパティの属性ごと書き換えることが可能なので、アクセサ型のpropertyの書き換えも可能。
  • かつてはObject.__defineGetter__とかdefineSetterもあったが非推奨になった
  • definePropertyを使うことで後からgetterやsetterの追加も可能。ただし、definePropertyをデフォルトオプションで使ってPropertyを追加すると、通常のプロパティ宣言とかなり挙動が異なる。(キーが列挙されない、書き換え不可になるなど)注意が必要
7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?