ゲッター

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 演算子によるゲッターの削除

getter を削除したい場合は、delete を使用します。

delete obj.latest;

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

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

var o = {a: 0};

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

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

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

var expr = 'foo';

var 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() の使用は似た結果になりますが、クラス上で使用する場合は微妙な違いがあります。

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 Latest Draft (ECMA-262)
Method definitions の定義
ドラフト
ECMAScript 2015 (6th Edition, ECMA-262)
Method definitions の定義
標準 computed property names を追加。
ECMAScript 5.1 (ECMA-262)
Object Initializer の定義
標準 初回定義

ブラウザーの互換性

Update compatibility data on GitHub
デスクトップモバイルサーバー
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung InternetNode.js
getChrome 完全対応 1Edge 完全対応 ありFirefox 完全対応 2IE 完全対応 9Opera 完全対応 9.5Safari 完全対応 3WebView Android 完全対応 1Chrome Android 完全対応 18Firefox Android 完全対応 4Opera Android 完全対応 ありSafari iOS 完全対応 ありSamsung Internet Android 完全対応 ありnodejs 完全対応 あり
Computed property namesChrome 完全対応 46Edge 完全対応 ありFirefox 完全対応 34IE 未対応 なしOpera 完全対応 47Safari 未対応 なしWebView Android 完全対応 46Chrome Android 完全対応 46Firefox Android 完全対応 34Opera Android 完全対応 ありSafari iOS 未対応 なしSamsung Internet Android 完全対応 5.0nodejs 完全対応 あり

凡例

完全対応  
完全対応
未対応  
未対応

関連情報