このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

JavaScriptのクラスもどきで、getter/setter を使う

JavaScriptでクラスもどきを定義するとき、次のような書き方があります。

// パッケージ
var shape = {};
// コンストラクタ
shape.Point = function (x, y) {
 this.x = x;
 this.y = y;
};
// クラス変数やメソッド
shape.Point.prototype = {
 moveTo : function (toX, toY) {
           this.x = toX;
           this.y = toY;
          },
 // 以下略
};

僕はこのスタイルを使っていませんでした(代わりに大域変数を1つゴミにしている例は「JavaScriptで言語処理系の勉強をしましょう:字句解析編」)。特にこれといった理由はなくて、「インデントどうしたらいいかわかんない」とか、その程度の事情です。

しかし、プロパティのgetter/setterを使うときは、上の書き方しかないような気がします。(ひょっとすると、別な書き方でもgetter/setterが使えるのかもしれません; ご存知の方は教えてください。)

例題として、Pointクラスにcolorを追加したものを使いましょう。colorは、RGBを表す3つの数値からなる配列とします。

// パッケージ
var shape = {};
// コンストラクタ
shape.Point = function (x, y) {
 this.x = x;
 this.y = y;
};
// クラス変数やメソッド
shape.Point.prototype = {
 color : [0, 0, 0], // デフォルト値
 moveTo : function (toX, toY) {
           this.x = toX;
           this.y = toY;
          },
 // 以下略
};

これだけでも、Pointのインスタンスはcolorの初期値を持ちます。個別にcolorを設定したいなら、p.color = [255, 0, 0] のようにしてできます。

フィールドアクセスや代入を生で使うよりは洒落た方法を使いたいなら、IEを除くたいていのブラウザでgetter/setterが使えます。

// クラス変数やメソッド
shape.Point.prototype = {
 _color : [0, 0, 0], // デフォルト値
 get color() {
  return this._color;
 },
 set color(c) {
  this._color = c;
 },
 moveTo : function (toX, toY) {
           this.x = toX;
           this.y = toY;
          },
 // 以下略
};

こうすると、p.color (参照)とか p.color = [255, 0, 0] (代入)とかのタイミングで関数が呼び出されます。もっとも、これだけでは以前と変わりません。色名(文字列)を、RGB数値配列に変換する処理を入れてみます。

// クラス変数やメソッド
shape.Point.prototype = {
 _color : [0, 0, 0], // デフォルト値
 get color() {
  return this._color;
 },
 set color(c) {
  if (typeof(c) === 'string') {
   var col = this.colorValue[c];
   if (col) {
    this._color = col;
   }
  } else if (c instanceof Array && c.length === 3) {
   // 配列の各項目のチェックは省略
   this._color = c;
  }
  // その他は何もしない
 },
 colorValue : {
  "black" : [0, 0, 0],
  "white" : [255, 255, 255],
  "red"   : [255, 0, 0],
  "green" : [0, 255, 0],
  "blue"  : [0, 0, 255]
 },
 moveTo : function (toX, toY) {
           this.x = toX;
           this.y = toY;
          },
 // 以下略
};

これで、p.color = "red"; のような書き方もできるようになります。便利ですね。