私はJavascriptで古いJavaプロジェクトを再構築していますが、JSで列挙型を作成するには良い方法がないことに気付きました。
私が思い付くことができる最高のものは:
const Colors = {
RED: Symbol("red"),
BLUE: Symbol("blue"),
GREEN: Symbol("green")
};
Object.freeze(Colors);
const
はColors
が再割り当てされるのを防ぎ、凍結することでキーと値の変更を防ぎます。 Colors.RED
が0
、またはそれ以外の何かに等しくないように、私はSymbolsを使っています。
この定式化に問題はありますか?もっと良い方法はありますか?
(この質問はちょっとした繰り返しであることを私は知っていますが、以前の 以前のQ/As は非常に古く、ES6によればいくつかの新しい機能。)
編集:
シリアライゼーションの問題に対処するもう1つの解決策。ただし、まだレルムの問題があると思います。
const enumValue = (name) => Object.freeze({toString: () => name});
const Colors = Object.freeze({
RED: enumValue("Colors.RED"),
BLUE: enumValue("Colors.BLUE"),
GREEN: enumValue("Colors.GREEN")
});
値としてオブジェクト参照を使用することで、Symbolsと同じ衝突回避が得られます。
この定式化に問題はありますか?
見えません。
もっと良い方法はありますか?
2つのステートメントを1つにまとめます。
const Colors = Object.freeze({
RED: Symbol("red"),
BLUE: Symbol("blue"),
GREEN: Symbol("green")
});
Symbol
の繰り返し呼び出しのように定型句が気に入らない場合は、もちろん、名前のリストから同じものを作成するヘルパー関数makeEnum
を書くこともできます。
TypeScriptがどのように動作するか を確認してください 。基本的に彼らは以下のことを行います。
const MAP = {};
MAP[MAP[1] = 'A'] = 1;
MAP[MAP[2] = 'B'] = 2;
MAP['A'] // 1
MAP[1] // A
あなたが望むものは何でも、シンボルを使用して、オブジェクトを凍結してください。
Enum値としてSymbol
を使用することは単純なユースケースのためにうまく働きますが、enumにプロパティを与えることは便利かもしれません。これは、プロパティを含む列挙値としてObject
を使用することによって実行できます。
たとえば、それぞれのColors
に名前と16進値を付けることができます。
/**
* Enum for common colors.
* @readonly
* @enum {{name: string, hex: string}}
*/
const Colors = Object.freeze({
RED: { name: "red", hex: "#f00" },
BLUE: { name: "blue", hex: "#00f" },
GREEN: { name: "green", hex: "#0f0" }
});
Enumにプロパティを含めることで、switch
ステートメントを書く必要がなくなります(そしてenumが拡張されたときにswitchステートメントの新しいケースを忘れることもあります)。この例では、 JSDoc enumアノテーション で文書化されたenumプロパティと型も示しています。
Colors.RED === Colors.RED
がtrue
で、Colors.RED === Colors.BLUE
がfalse
であれば、平等は期待通りに働きます。
ES6列挙型の非常に優れた機能を備えたライブラリである Enumify を確認できます。
上記のように、makeEnum()
ヘルパー関数を書くこともできます。
function makeEnum(arr){
let obj = {};
for (let val of arr){
obj[val] = Symbol(val);
}
return Object.freeze(obj);
}
このように使用してください。
const Colors = makeEnum(["red","green","blue"]);
let startColor = Colors.red;
console.log(startColor); // Symbol(red)
if(startColor == Colors.red){
console.log("Do red things");
}else{
console.log("Do non-red things");
}
あなたが純粋なES6を必要とせず、TypeScriptを使うことができるなら、それはNice enum
を持っています:
これが私の個人的なやり方です。
class ColorType {
static get RED () {
return "red";
}
static get GREEN () {
return "green";
}
static get BLUE () {
return "blue";
}
}
// Use case.
const color = Color.create(ColorType.RED);
たぶんこの解決策? :)
function createEnum (array) {
return Object.freeze(array
.reduce((obj, item) => {
if (typeof item === 'string') {
obj[item] = Symbol(item)
}
return obj
}, {}))
}