2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

jsで列挙型的データ構造で分岐処理を記載する

Last updated at Posted at 2025-06-09

動機

以下のように分岐処理を記載するため、列挙型的データ構造(MY_ENUMの中身)を考案しました。

const MY_ENUM = {/* ? */};
// ...
const e = MY_ENUM.key0;
// ...
if (e.key0) {
    // ...このブロックにはいる...
} else if (e.key1 || e.key2) {
    // ...
} else if (e.key3) {
    // ...
} else {
    // ...
}

この例の場合、列挙型的データ構造は最低限、以下でないといけません。

const MY_ENUM = {
    'key0':{'key0':true,},
    'key1':{'key1':true,},
    'key2':{'key2':true,},
    'key3':{'key3':true,},
    // ...
};

本案で解決される課題

本案は、以下のようなプログラムから移行するために考案しました。

switch句

分岐が英単語(casedefaultbreak)で表されるため見ずらい、break漏れによる意図しない落下(fall-through)、分岐で字句スコープが作成されない問題、などがあり、好ましく思わない意見があります。

const key = 'key0';
// ...
switch (key) {
case 'key0':
    // ...このブロックにはいる...
    break;
case 'key1':
case 'key2':
    // ...
    break;
case 'key3':
    // ...
    break;
default:
    // ...
}

文字列型を使用して判定

key===冗長記載による可読性の低下が気になります。

const key = 'key0';
// ...
if (key==='key0') {
    // ...このブロックにはいる...
} else if (key==='key1' || key==='key2') {
    // ...
} else if (key==='key3') {
    // ...
} else {
    // ...
}

ユニークな値を持つ連想配列(固定化したオブジェクト)

key===MY_ENUM.冗長記載による可読性の低下が気になります。

const MY_ENUM = Object.freeze({
    'key0':0,
    'key1':1,
    'key2':2,
    'key3':3,
    // ...
});
// ...
const key = MY_ENUM.key0;
// ...
if (key===MY_ENUM.key0) {
    // ...このブロックにはいる...
} else if (key===MY_ENUM.key1 || key===MY_ENUM.key2) {
    // ...
} else if (key===MY_ENUM.key3) {
    // ...
} else {
    // ...
}

連想配列の値に関数を定義

ケースによると考えます。

const MY_ENUM = {
    'key0':()=>{/*...このブロックにはいる...*/},
    'key1':()=>{/*...*/},
    'key3':()=>{/*...*/},
    // ...
    'defaultKey':()=>{/*...*/},
};
MY_ENUM['key2'] = MY_ENUM['key1'];
Object.freeze(MY_ENUM);
// ...
const key = 'key0';
// ...
(MY_ENUM[key] ?? MY_ENUM['defaultKey'])();

付加情報

最低限の列挙型的データ構造だと、e.key0trueまたはundefinedになります。
例えばelem.classList.toggle('className', e.key0)としたい場合などで、e.key0の値をtrueまたはfalseにしたいなら、最低限以下のデータ構造にしないといけません。

const MY_ENUM = {
    'key0':{'key0':true,'key1':false,'key2':false,'key3':false,/*...*/},
    'key1':{'key0':false,'key1':true,'key2':false,'key3':false,/*...*/},
    'key2':{'key0':false,'key1':false,'key2':true,'key3':false,/*...*/},
    'key3':{'key0':false,'key1':false,'key2':false,'key3':true,/*...*/},
    // ...
};

データ構造を作成する関数を作ることができます。
以下は最低限の列挙型的データ構造を作成する場合。

const makeEnum = keys=>{
    const m = {};
    for (const k of keys.split(' ')) {
        m[k] = Object.freeze({[k]:true,});
    }
    return Object.freeze(m);
};
// ...
const MY_ENUM = makeEnum('key0 key1 key2 key3');
// ...
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?