dev blog

プログラミングめも

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 = 20user._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は、プロパティの値を読み出す際に適切な値を計算して返す必要がある場合や、プロパティの値を加工してから書き込む場合などに便利な機能です。