ゲッターとセッターの定義
ゲッターはある属性の値を取得するメソッドです。セッターは属性にの値を設定するメソッドです。全ての定義済みコアオブジェクトと、新しいプロパティの追加をサポートしているユーザ定義オブジェクトに対してゲッターとセッターを定義できます。ゲッターとセッターの定義にはオブジェクトリテラル構文を使用します。
以下の例では、ユーザ定義オブジェクト o についてゲッターとセッターがどのように機能するかを説明します。JavaScript シェル とは JavaScript コードをバッチモードで、またはインタラクティブにテストすることができる、開発者向けのアプリケーションのことです。
o
オブジェクトのプロパティは以下のとおりです。
- o.a - 数値
- o.b - o.a に 1 を加えて返すゲッター
- o.c - o.a の値にその値の 1/2 の値をセットするセッター
js> o = new Object; [object Object] js> o = {a:7, get b() {return this.a+1; }, set c(x) {this.a = x/2}}; [object Object] js> o.a 7 js> o.b 8 js> o.c = 50 js> o.a 25 js>
次の例では、 Date プロトタイプを拡張して定義済み Date
クラスの全インスタンスに year プロパティを追加する様子を表しています。Date
クラスの既存の getFullYear
および setFullYear
メソッドを使用して year プロパティのゲッターとセッターを実装します。
これらの文は year プロパティに対するゲッターとセッターを定義しています。
js> var d = Date.prototype; js> d.__defineGetter__("year", function() { return this.getFullYear(); }); js> d.__defineSetter__("year", function(y) { this.setFullYear(y); });
これらの文は Date
オブジェクトで定義したゲッターとセッターを使用しています。
js> var now = new Date; js> print(now.year); 2000 js> now.year=2001; 987617605170 js> print(now); Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001
getter =
や setter =
といった式を使用して新しいゲッターやセッターを既存のオブジェクトで定義するようになっていた時期がありました。この構文は現在は廃止予定であり、現行の JS 1.5 エンジンでは警告を発します。また、将来的には構文エラーになります。使用を避けるようにしてください
概要
原則的にゲッターとセッターは次のどちらかに属します。
- オブジェクト初期化子 を用いて定義されたもの
- ゲッターやセッターを追加するメソッドを用いてオブジェクトに後から追加されたもの
オブジェクト初期化子 を用いてゲッターやセッターを定義する際には、ゲッターメソッドの先頭に get
を、セッターメソッドの先頭に set
をそれぞれ付けなくてはなりません。セッターメソッドはセットする新しい値を受けわたすための引数を 1 つだけ持ちます。ゲッターメソッドはパラメータを受け取るようにしてはいけません。
o = { a:7, get b() { return this.a+1; }, set c(x) { this.a = x/2; } };
ゲッターもセッターも、__defineGetter__
および __defineSetter__
という 2 つの特別なメソッドを用いて、オブジェクト作成後でも、そのオブジェクトに追加することができます。両メソッドの第 1 引数にはそのゲッターやセッターの名前を文字列で指定します。第 2 引数にはゲッターやセッターとして呼び出す関数を指定します。前の例を別の方法で実装したものを以下に示します。
o.__defineGetter__("b", function() { return this.a+1; }); o.__defineSetter__("c", function(x) { this.a = x/2; });
2 つの形式のうちどちらを選択するかはあなたのプログラミングスタイルや、目の前の課題次第によります。プロトタイプの定義時にオブジェクト初期化子を使用しているのであれば、最初の形式を選択するのがよいでしょう。この形式はよりコンパクトかつ自然です。ゲッターやセッターを後から追加する必要がある場合は、プロトタイプや特定のオブジェクトを書いていないため、第 2 の形式しか使用できません。第 2 の形式は JavaScript の動的性質をおそらく最もよく表していますが、コードが可読性が下がったり、理解しづらいものとなることがあります。
Firefox 3.0 より前のバージョンではゲッターとセッターが DOM 要素に対してサポートされていません。古いバージョンの Firefox では例外を投げることなく失敗します。そのときに例外が必要であれば、HTMLElement のプロトタイプを変更し (HTMLElement.prototype.__define[SG]etter__)
、例外を投げるようにして回避してください。
Firefox 3.0 では、定義済みのプロパティでゲッターとセッターを定義すると例外が投げられます。そのプロパティは事前に削除しておく必要があります。これは古いバージョンの Firefox には当てはまりません。