【JavaScript】擬似列挙型

謎のプリン語る。
プログラミングの役立つ情報とか、どうでもいい雑談とか書いてます。
一人書く人増えました。

【JavaScript】擬似列挙型

2020年03月25日

みやびプリン 500 316

500 320

【JavaScript】擬似列挙型 - サムネイル

どうも。
だいぶ寝不足なみやびです。

今日はさっさと寝よう、マジで。

さて、列挙型といえば、めちゃんこ便利なデータ型だ。
とくにアプリケーションとかの大規模開発においては、開発効率の向上に非常に貢献できるデータ型であると言えよう。
だが、これ、性質的にしゃーないのだが、動的型付けの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!');
    }
  }
}

ありえないほど簡単にホームページができる【Jimdo(ジンドゥー)】 - メイン

使い方は下記のような感じ。

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でも使っていきたいとなればどうかご参考あれ。

黒い砂漠 - メイン

トラックバック(0)

トラックバックURL:

コメントする

ページトップへ戻る