※この記事は4年以上前の記事です。
現在は状況が異なる可能性がありますのでご注意ください。
どうも。
だいぶ寝不足なみやびです。
今日はさっさと寝よう、マジで。
さて、列挙型といえば、めちゃんこ便利なデータ型だ。
とくにアプリケーションとかの大規模開発においては、開発効率の向上に非常に貢献できるデータ型であると言えよう。
だが、これ、性質的にしゃーないのだが、動的型付けの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でも使っていきたいとなればどうかご参考あれ。
コメントする