JavaScriptでも列挙型が使いたいです。
列挙型 = Enum = Enumerated type
JavaScriptでは列挙型は使えないし、
かといって自前で何かするのも面倒です、
そんな時、便利なものを見つけました。
その名も enum.js というライブラリ
使い方とかコード例を色々紹介していきます。
このページの目次
列挙型いわゆるEnumとは何か?その概要
ここは説明は不要かもしれません。
でも念のために概要を説明します。
▼ 概要はWikiとか見ればいい
列挙型(れっきょがた、enumerated typeあるいはenumeration type)とは、コンピュータプログラミングにおいて、プログラマが選んだ各々の識別子(列挙子)をそのまま有限集合として持つ抽象データ型である。列挙型は一般に、カードのスートのように番号順を持たないカテゴリ変数として使われるが、実際のコンパイル時あるいは実行時には、列挙型は整数で実装されることが多い。
引用元 : https://ja.wikipedia.org/wiki/%E5%88%97%E6%8C%99%E5%9E%8B
▼ 同Wikiに載ってたCでの列挙型例
1 2 3 4 5 6 |
enum cardsuit { CLUBS, DIAMONDS, HEARTS, SPADES }; |
列挙型ではコンパイル・実行時に自動で番号が割り振られます。上記のenumだったら CLUBS = 0, DIAMONDS = 1, HEARTS = 2, SPADES = 3 みたいな感じで…
定数定義とかフラグ管理に便利です。
でもJavaScriptにはそんな機能はない。
1.初めにenum.jsをインストール・読込
ここで使用するのは次のライブラリです。
▼ Github : adrai / enum
ライセンスもMITだから安心。
ブラウザ・Node.jsの両方にも対応してます。
▼ Node.jsならnpmからインスト
1 |
$ npm install enum |
▼ ブラウザならCDNから読込
1 2 |
<!-- フッター付近で読込とかする --> <script src="/path/to/enum.min.js"></script> |
最新バージョンは3.0.4でした。
ちなみにGitHubの最終更新は2年前になっています。でも放置されてるというより「枯れた技術」だから更新の必要がないのかもしれません。
ということでenumを使う下準備は完了
2.Enumを使って列挙型を定義する
それでは簡単に列挙型を定義してみます。
名前もそのまま Enum を使うだけです。
▼ とてもシンプルな列挙型定義コード例
1 2 3 4 5 6 7 8 9 10 |
/// 色の列挙型定義 const Colors = new Enum([ 'RED', 'GREEN', 'BLUE' ]); console.log('RED : ', Colors.RED); console.log('GREEN : ', Colors.GREEN); console.log('BLUE : ', Colors.BLUE); |
▼ 上記コードの出力結果
1 2 3 4 5 6 7 8 9 |
RED : { key: 'RED', value: 1 } GREEN : { key: 'GREEN', value: 2 } BLUE : { key: 'BLUE', value: 4 } |
上記コードを見ての通り new Enum(['RED', 'GREEN', 'BLUE']) として、列挙型にしたい配列をそのまんま渡すだけです。
そして列挙型は以下の特長を持ちます。
▼ Enumにより定義される列挙型の特長
- 列挙子はキー・値を持つ
例えば Colors.RED を参照した場合、それは {key: 'RED', 'value': 1 } のようにキー・値を持つオブジェクトとして定義されている。
- 列挙子の値は2^n(n=1)が割り振られる
列挙型の列挙子には 2のn乗(n=0) という規則で番号(=value)が割り振られる。これは論理和などをしやすくするため
言語的に実装されたEnumとは少し違います。
例えばC言語だったら Colors.RED = 0 だけど、enum.jsではキー・値を持つオブジェクトを返してくることに注意が必要です。
つまりC言語的に Colors.RED にアクセスしたいなら、enum.jsでは Colors.RED.value とする必要があるわけですね。そこ注意なので気を付けて
でも簡単に列挙型もどきが使えて便利です。
3.列挙型同士の比較には注意が必要
もう1つ注意点があって、それが比較方法
これには色々な方法があるみたいです。
▼ Enum同士の正しい比較コード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/// 色の列挙型定義 const Colors = new Enum([ 'RED', 'GREEN', 'BLUE' ]); /// 列挙型の名前で比較 console.log(Colors.RED.is(Colors.RED)) // 列挙型のキーで比較 console.log(Colors.RED.is('RED')) // 列挙型の値=連番で比較 console.log(Colors.RED.is(1)) // 列挙型を == で比較 console.log(Colors.RED == Colors.RED) // 列挙型を === で比較 console.log(Colors.RED === Colors.RED) |
こういう感じで比較をすることが可能。
そして注意点は異なる列挙型同士の倍です。
たとえば同じ配列から生成した列挙型だとしても、
以下のように異なるインスタンスなら比較できません。
▼ こういうコードはダメ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
const ColorsA = new Enum([ 'RED', 'GREEN', 'BLUE' ]); const ColorsB = new Enum([ 'RED', 'GREEN', 'BLUE' ]); console.log(ColorsA.RED == ColorsB.RED); /// => false |
比較は同じ列挙型の要素同士でしかできません。
4.列挙子の値をそれぞれ指定も可能
それから列挙型生成時の列挙子について。
列挙子の値は個別に指定することも可能です。
▼ こういうコード
1 2 3 4 5 6 7 8 9 |
const Colors = new Enum({ 'RED': 0, 'GREEN': 1, 'BLUE': 2 }); console.log('RED : ', Colors.RED); console.log('GREEN : ', Colors.GREEN); console.log('BLUE : ', Colors.BLUE); |
▼ 上記コードの出力結果
1 2 3 |
RED : { key: 'RED', value: 0 } GREEN : { key: 'GREEN', value: 1 } BLUE : { key: 'BLUE', value: 2 } |
もしC言語ライクに 0、 1、 2、 … として列挙子の値を割り振りたいなら、上記のようにオブジェクトを渡すこともできます。
こういう気の利いたオプションもあります。
このEnum.jsを使うメリットは何か
もしキー・値のペアならオブジェクトで十分です。
それでもEnum.jsを使うメリットは次の点にあります。
- 自動で列挙子に番号を割り振ってくれる
- 列挙子同士の論理和などが取りやすい
- 列挙型内のキーも文字列として取得できる
以上、JSで列挙型=Enumを扱うでした。
ただし言語的なEnumとはやはり別物です。
そこらへんは気を付けて使った方がいいと思います。