JavaScript|getterとsetter
getterとsetterの備忘録です。
オブジェクトについておさらい
オブジェクトは、プロパティの集まりです。
プロパティとは、name: 'John'
といった名前(キー)と値のセットのことです。
プロパティの値には、データだけではなく関数も定義できます。この関数をメソッドと呼びます。
user
オブジェクトに、name
age
のデータとgreet
メソッドを定義してみます。
const user = { name: 'John', age: 25, greet() { console.log('Hello!') } }
このようにオブジェクトにアクセスすることができます。
console.log(user.name) // => John user.greet() // => Hello!
getterとsetterとは
オブジェクトのプロパティは、
- データプロパティ
- アクセサプロパティ
の2種類に分類されます。
データプロパティとは、最初に書いたコードのように値や関数を格納しているプロパティのことです。対してアクセサプロパティは、値を格納しません。getterメソッドやsetterメソッドを定義します。
- getterメソッド(オブジェクト内のプロパティの値を読み出す)
- setterメソッド(オブジェクト内のプロパティに値を書き込む)
getterを使ってみる
では実際にgetterメソッドを書いてみます。
const user = { firstName: 'John', lastName: 'Smith', get fullName() { return this.firstName + ' ' + this.lastName } } console.log(user.fullName) // => John Smith
getterしか定義されていない場合は、読み込み専用プロパティとなるので、値を書き込んでも無視されます。
user.fullName = 'John' console.log(user.fullName) // => John Smith // 値が変わっていない
ちなみに、getterとデータプロパティの両方に同名のfullName
が存在していると、データプロパティのfullName
は無視されます。
const user = { firstName: 'John', lastName: 'Smith', fullName: 'JOHN SMITH', // 同名のデータプロパティを追加 get fullName() { return this.firstName + ' ' + this.lastName } } console.log(user.fullName) // => John Smith // getterのfullNameが読み出されている user.fullName = 'John' console.log(user.fullName) // => John Smith // データプロパティのfullNameへ書き込んでも無視される
setterを使ってみる
続いてsetterメソッドを書いてみます。
setterメソッドは引数(セットする新しい値)を1つだけ持ちます。
const user = { firstName: 'John', lastName: 'Smith', _team: '', set team(value) { if (value <= 10) { this._team = 'team A' } else if (value > 10) { this._team = 'team B' } } } user.team = 7 console.log(user._team) // => team A
setterしか定義していない場合は、書き込み専用プロパティとなるので、値を読み出すことはできません。
console.log(user.team)
// => undefined
また、上記のコードでデータプロパティは_team
、setterはteam
としていますが、両方ともteam
とするとどうなるでしょう。
const user = { firstName: 'John', lastName: 'Smith', team: '', // こちらもteamに変更 set team(value) { if (value <= 10) { this.team = 'team A' } else if (value > 10) { this.team = 'team B' } } } user.team = 7 console.log(user.team) // => undefined
setterを使ったuser.team
への書き込みも、データプロパティuser.team
の読み出しもうまく動作しません。
getterとsetterの使いどころ
プロパティを値の読み書きにしか使用しない場合は、データプロパティをそのまま使用すればよいので、あえてgetterやsetterを使用する必要はありません。
user.age = 20
もuser._age = 20
も同じことをしています。
const user = { firstName: 'John', lastName: 'Smith', _age: 0, get age() { return this._age }, set age(value) { this._age = value } } user.age = 20 console.log(user.age) // => 20 user._age = 20 console.log(user._age) // => 20
getterやsetterは、プロパティの値を読み出す際に適切な値を計算して返す必要がある場合や、プロパティの値を加工してから書き込む場合などに便利な機能です。