【JavaScript】Symbolを駆使してenumぽいものを定義する

プログラム全般

概要

JavaScriptでsymbol型を使う事によって、enumっぽいものの実装ができます。
そこそここなれてきたので紹介します。

前説

JavaScriptでenumを作るパターン

JavaScriptではenumが基本無いので、あの手この手でenumっぽいものを作る必要があります。

単純にconstで定義するパターン

こういうの

const ENUM = {
HOGE: "hoge",
FUGA: "fuga,
}
function isHoge(enum) {
return enum === ENUM.HOGE);
}

www.sohamkamani.com

enumクラスを自作

qiita.com

他にもあると思います。

何が不満?

enumっぽいけど実体はただのObjectなので、enumを使わないでサボった実装でも動いてしまいます。

const ENUM = {
HOGE: "hoge",
FUGA: "fuga,
}
function isHoge(enum) {
return enum === ENUM.HOGE);
}
// 想定された使われ方
isHoge(ENUM.HOGE); // true
// さぼった使われ方
isHoge("hoge"); // true

Symbol(シンボル)とは

qiita.com

まあ今回のネタはほとんどこちらに書いてあるのですが、ポイントは

console.log(Symbol("Hoge") === Symbol("Hoge"));
// false

という事です。RubyのSymbolとはだいぶイメージが違うので気をつけましょう。

実装

const ENUM = {
HOGE: Symbol("hoge"),
FUGA: Symbol("fuga),
}
function isHoge(enum) {
return enum === ENUM.HOGE);
}
// 想定された使われ方
isHoge(ENUM.HOGE); // true
// さぼった使われ方
isHoge("hoge"); // false
isHoge(Symbol("hoge")); // false

はい、これでENUMを使うことを強制できました。

jsonにしたり、シリアライズしてDBに保存したりしたい時は、

enumKeyString(enum) {
switch (enum) {
case ENUM.HOGE:
return "hoge";
case ENUM.FUGA:
return "fuga";
]
}

とか

const ENUM_KEY_STRING = {
[ENUM.HOGE]: "hoge",
[ENUM.FUGA]: "fuga",
}

とかを用意してSymbolじゃない型でシリアライズしてあげるくらいしか手がありません。
ださいしめんどくさい、、、

Symbol("hoge")hogeはdescriptionなので、ロジックには使いたく無い。toStringしてもSymbol(hoge) になる、、、微妙、、

※typescriptを使えばいいじゃん、とか言わない事

コメント

タイトルとURLをコピーしました