Перечисления в Javascript с ES6


я перестраиваю старый проект Java в Javascript и понял, что нет хорошего способа сделать перечисления в JS.

лучшее, что я могу придумать-это:

const Colors = {
    RED: Symbol("red"),
    BLUE: Symbol("blue"),
    GREEN: Symbol("green")
};
Object.freeze(Colors);

The const держит Colors от переназначения и замораживания он предотвращает изменение ключей и значений. Я использую символы, так что Colors.RED не равно 0, или что-нибудь еще, кроме себя.

есть ли проблема с этой формулировкой? Есть ли лучше путь?


(я знаю, что этот вопрос немного повторяется, но все предыдущие Q/As довольно старые, и ES6 дает нам некоторые новые возможности.)


EDIT:

еще одно решение, которое касается проблемы сериализации, но я считаю, что все еще есть проблемы с областью:

const enumValue = (name) => Object.freeze({toString: () => name});

const Colors = Object.freeze({
    RED: enumValue("Colors.RED"),
    BLUE: enumValue("Colors.BLUE"),
    GREEN: enumValue("Colors.GREEN")
});

используя ссылки на объекты в качестве значений, вы получаете то же самое предотвращение столкновений, что и символы.

8 60

8 ответов:

есть ли проблема с этой формулировкой?

Я ничего не вижу.

есть ли лучший способ?

Я бы свернул два утверждения в одно:

const Colors = Object.freeze({
    RED:   Symbol("red"),
    BLUE:  Symbol("blue"),
    GREEN: Symbol("green")
});

Если вам не нравится шаблон, как повторяется Symbol вызовы, вы можете, конечно, также написать вспомогательную функцию makeEnum что создает то же самое из списка имен.

также проверить Enumify, очень хорошая и хорошо показанная библиотека для перечислений ES6.

надеюсь, что это поможет кому-то.

с уважением,

Эммануэль

Как упоминалось выше, вы также можете написать 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");
}

Регистрация как TypeScript делает это. В основном они делают следующее:

const MAP = {};

MAP[MAP[1] = 'A'] = 1;
MAP[MAP[2] = 'B'] = 2;

MAP['A'] // 1
MAP[1] // A

используйте символы, заморозить объект, все, что вы хотите.

Если вам не нужен чисто ES6 и может использовать Typescript, он имеет хороший enum:

https://www.typescriptlang.org/docs/handbook/enums.html

вы также можете использовать пакет es6-enum (https://www.npmjs.com/package/es6-enum). это очень простой в использовании. Смотрите пример ниже

вы можете использовать ES6 Map

const colors = new Map([
  ['RED', 'red'],
  ['BLUE', 'blue'],
  ['GREEN', 'green']
]);

console.log(colors.get('RED'));

Это мой личный подход.

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);