ゲッター

get 構文は、オブジェクトのプロパティを関数に結びつけ、プロパティが参照された時に関数が呼び出されるようにします。

構文

{get prop() { ... } }
{get [expression]() { ... } }

引数

prop
与えられた関数に結び付けられるプロパティの名前
expression
ECMAScript 6 より、算出されたプロパティ名 (computed property name) の式を使用して関数に結び付けることもできます。

解説

時として、動的に計算した値を返すプロパティにアクセスを許可したほうが望ましい場合や、明示的なメソッドを呼び出すことなく内部変数に状態を反映させたい場合があります。 JavaScript では、ゲッターを使ってこれを行うことが可能です。

プロパティに結び付けられたゲッターと、実際に値を持つプロパティを同時に持つことはできませんが、ゲッターとセッターを組み合わせて使用し、一種の擬似プロパティを作成することはできます。

get 構文を使用する際の注意事項:

  • 数値または文字列による識別子を持つことができます。
  • パラメータの数は 0 でなければなりません (詳しくは Incompatible ES5 change: literal getter and setter functions must now have exactly zero or one arguments をご覧ください)。
  • 1つのオブジェクトリテラル中に、同じプロパティに対する別の get またはデータの割り当てが現れてはいけません ({ get x() { }, get x() { } }{ x: ..., get x() { } } は禁止されています)。

オブジェクト初期化時における新しいオブジェクトのゲッターの定義

以下の例では、オブジェクト obj の擬似プロパティとして、 log 内の最後の配列アイテムを返す latest プロパティを作成します。

const obj = {
  log: ['example','test'],
  get latest() {
    if (this.log.length === 0) return undefined;
    return this.log[this.log.length - 1];
  }
}
console.log(obj.latest); // "test"

latest に値を代入しようとしても、変更はされないことに注意して下さい。

delete 演算子によるゲッターの削除

ゲッターを削除したい場合は、 delete を使用します。

delete obj.latest;

既存のオブジェクトへの defineProperty を使用したゲッターの定義

任意のタイミングで既存のオブジェクトにゲッターを追加するには、 Object.defineProperty() を使用します。

const o = {a: 0};

Object.defineProperty(o, 'b', { get: function() { return this.a + 1; } });

console.log(o.b) // getter を実行。a + 1 を算出する (結果は 1)

算出されたプロパティ名の使用

const expr = 'foo';

const obj = {
  get [expr]() { return 'bar'; }
};

console.log(obj.foo); // "bar"

スマート / 自己書き換え / 怠惰なゲッター

ゲッターはオブジェクトのプロパティを定義する手段を提供しますが、アクセスされるまでプロパティの値を計算しません。ゲッターは値を計算するコストを、値が必要になるまで先送りします。値が必要でなければ、そのコストを負担しません。

プロパティの値の計算を先送りしたり後のアクセスのためにキャッシュするための付加的な最適化技術が、スマート (またはメモ化) ゲッターです。初めてゲッターにアクセスされたときに、値を計算してキャッシュします。以降のアクセスでは再計算せずに、キャッシュした値を返します。これは次のような状況で役に立ちます。

  • プロパティの値の計算コストが高い場合 (大量の RAM や CPU 時間を使用する、ワーカースレッドを生成する、リモートのファイルを読み込むなど)。
  • 値がすぐに必要ではない場合。値を後で使用する、あるいはまったく使用しない場合がある状況。
  • 何度もアクセスされる値で、値が変更されないため再計算の必要がない、あるいは再計算すべきではない場合。

値が変わると見込まれるプロパティで、怠惰なゲッターを使用してはいけません。このようなゲッターは値を再計算しないためです。

以下の例では、オブジェクトが自身のプロパティとしてゲッターを持っています。プロパティを取得すると、プロパティはオブジェクトから削除された後に再追加されますが、このとき暗黙的にデータプロパティとして追加されます。最終的に、値が返されます。

get notifier() {
  delete this.notifier;
  return this.notifier = document.getElementById('bookmarked-notification-anchor');
},

Firefox のコードでは、 XPCOMUtils.jsm コードモジュールもご覧ください。これは defineLazyGetter() 関数を定義しています。

getdefineProperty

get キーワードと Object.defineProperty() の使用は似た結果になりますが、 classes 上で使用する場合は微妙な違いがあります。

get を使用した場合は、プロパティはインスタンスのプロトタイプに定義されるのに対し、 Object.defineProperty() を使用した場合は、プロパティは適用されたインスタンスに定義されます。

class Example {
  get hello() {
    return 'world';
  }
}

const obj = new Example();
console.log(obj.hello);
// "world"

console.log(Object.getOwnPropertyDescriptor(obj, 'hello'));
// undefined

console.log(
  Object.getOwnPropertyDescriptor(
    Object.getPrototypeOf(obj), 'hello'
  )
);
// { configurable: true, enumerable: false, get: function get hello() { return 'world'; }, set: undefined }

仕様書

仕様書
ECMAScript (ECMA-262)
Method definitions の定義

ブラウザーの互換性

BCD tables only load in the browser

関連情報