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文で制御しています。