JavaScriptで自作クラスを作るときに問題となるprivateをどう実装するか、
とりあえずこんな感じだとどうだろう的なものを考えてみた。
ついでに他の言語っぽく変数定義→コンストラクタ→関数の順にも書きたかった。
private変数のあるクラス
例なので、とりあえず
- インスタンス数をprivate static
な変数で持っておいて、public static
な関数で取得
- カウント数をprivate
な変数で持っておいて、public
な変数でカウント吸うを増やしたりカウント数を取得したりする
というだけのクラスです。
test.js
(function () {
'use strict';
// private static 初期化
let _instanceCount = 0;
let Class = function () {
// public
let _public = this;
// private 初期化
let _count = 0;
// コンストラクタ
let _constructor = function () {
_instanceCount++;
};
_public.addCount = function () {
_count++;
};
_public.getCount = function () {
return _count;
};
_constructor();
};
// public static
Class.getInstanceCount = function () {
return _instanceCount;
};
}());
補足
- 実際には、
Class
をmyApp.Class
のような名前空間を作ってそこに代入して使う想定。 -
public static
を下にしかかけないのが辛い - 書いた本人は言語仕様に詳しくないのでもっと良い書き方があると思う
追記
- WeakMapを使った場合は以下のような感じ
test.js
(function () {
'use strict';
// WeakMap
let _weakMap = new WeakMap();
let _getPrivate = function(object) {
let map = _weakMap.get(object);
if(map === null) {
map = {};
_weakMap.set(object, map);
}
return map;
}
// private static 初期化
let _instanceCount = 0;
let Class = function () {
// public
let _public = this;
// private 初期化
let _private = getPrivate(this);
// コンストラクタ
let _constructor = function () {
_instanceCount++;
_private.count = 0;
};
_public.addCount = function () {
_private.count++;
};
_public.getCount = function () {
return _private.count;
};
_constructor();
};
// public static
Class.getInstanceCount = function () {
return _instanceCount;
};
}());
JavaScriptのclassも、classを使わずにこういう書き方するのもあまり好きじゃない・・・