マイナー・マイナー

隠れた名作の発掘が生きがい。

JavaScriptでクラス変数っぽいものを作る


スポンサードリンク

Javaで使われるクラス変数(static変数)、

class Hoge {
  static int hogera;
}


みたいな変数をJavaScriptで実現できないものかと試行錯誤しました。prototypeプロパティにオブジェクトをアタッチすればクラス変数っぽいものができそうです。クラス変数っぽいものと、比較のためにプライベート変数とパブリック変数を含んだオブジェクトを作成して、挙動を見てみました。結果はコメントの通り。

var Data = function() {
  var privateInfo = "private Data"; // プライベート変数
  this.publicInfo = "public Data"; // パブリック変数
 
  // クラス変数っぽいものを提供する
  var StaticInfo = function() {
    var _staticInfo = "static Data";
   
    this.getStaticInfo = function() {
      return _staticInfo;
    };

    this.setStaticInfo = function(info) {
      _staticInfo = info;
    }
  };
 
  // StaticInfoのインスタンス化は一度だけ
  if (!Data.prototype.staticInfo) {
    Data.prototype.staticInfo = new StaticInfo(); // クラス変数っぽいもの
  }
};


// インスタンス化
var data1 = new Data();
var data2 = new Data();
console.log(data1.privateInfo); // undefined
console.log(data1.publicInfo); // public Data
console.log(data1.StaticInfo); // undefined
console.log(data1.staticInfo.getStaticInfo()); // static Data
console.log(data2.privateInfo); // undefined
console.log(data2.publicInfo); // public Data
console.log(data2.StaticInfo); // undefined
console.log(data2.staticInfo.getStaticInfo()); // static Data


// data1のプロパティを更新してdata2の中身を見てみる
data1.publicInfo = "public data1";
data1.staticInfo.setStaticInfo("static data1");
console.log(data2.publicInfo); // public Data
console.log(data2.staticInfo.getStaticInfo()); // static data1


// data2のプロパティを更新してdata1の中身を見てみる
data2.publicInfo = "public data2";
data2.staticInfo.setStaticInfo("static data2");
console.log(data1.publicInfo); // public data1
console.log(data1.staticInfo.getStaticInfo()); // static data2


// 新しいインスタンスの中身はどうなっているか
var data3 = new Data();
console.log(data3.publicInfo); // public Data
console.log(data3.staticInfo.getStaticInfo()); // static data2


StaticInfoがクラス変数っぽいものを提供するコンストラクタで、インスタンス化してData.prototype.staticInfoにつなげています。わざわざコンストラクタ呼び出しで作らなくても、オブジェクトをそのままつなげても良さそうです。StaticInfoは一度だけインスタンス化されるようにif文で制御しています。