どうも。
だいぶ寝不足なみやびです。
今日はさっさと寝よう、マジで。
さて、列挙型といえば、めちゃんこ便利なデータ型だ。
とくにアプリケーションとかの大規模開発においては、開発効率の向上に非常に貢献できるデータ型であると言えよう。
だが、これ、性質的にしゃーないのだが、動的型付けのJavaScriptには存在しない。
(糖衣言語のTypeScriptには存在する)
ってわけで、作ってみよた、ってのが今回のエントリーってわけ。
いろんな人がやってみたりしてるが、ES6〜で、ってのはなかなかなかったので、
ガンガン使ってやってみた。
(ES6〜使用なので、IEには対応してない)
const EnumCaseStruct = (() => {
const key = Symbol();
return class EnumCaseStruct {
constructor(val) {
this[key] = val;
}
// Swiftを参考に、rawValueで、値を取得できるようにしている
get rawValue() {
return this[key];
}
};
})();
class Enum {
constructor(...cases) {
if (!cases.every(v => {
switch (typeof v) {
case 'object':
// オブジェクトの場合、各キー値にて、上のクラスのインスタンスとして定義
Object.keys(v).forEach(ve => {
Object.defineProperty(this, ve, {value: new EnumCaseStruct(v[ve])});
});
return true;
case 'string':
// 文字列型なら、そのまま初期化する
Object.defineProperty(this, v, {value: new EnumCaseStruct(v)});
return true;
defalult:
// オブジェクトか、文字列型以外は受け付けないようにする
return false;
}
})) {
// オブジェクトか文字列以外は、エラーをスローする
throw new Error('Type error!');
}
}
}
使い方は下記のような感じ。
const fruits = new Enum(
{apple: 25},
{melon: 125}
);
const apple01 = fruits.apple;
const apple02 = fruits.apple;
console.log(apple01 == apple02); // true
// 可変長引数のため、下記のようにも定義可能
const fruits02 = new Enum(
{
apple: 25,
melon: 125
},
'pine'
);
// 各列挙型は各値が一意となるため、比較時は偽となる。
console.log(fruits.apple == fruits02.apple); // false
// Swiftを参考に、rawValueにて、設定した値を返す
console.log(fruits.apple.rawValue); // 25
// 文字列をそのまま入れた場合は、rawValueはその文字列を返す
console.log(fruits.pine.rawValue); // pine
もちろん完全にというわけではないが、だいたいそれっぽく実装できたと思う。
列挙型を、JSでも使っていきたいとなればどうかご参考あれ。

コメントする