Я перестраиваю старый Java-проект в Javascript и понял, что в JS нет хорошего способа сделать перечисления.
Лучшее, что я могу придумать, это:
const Colors = {
RED: Symbol("red"),
BLUE: Symbol("blue"),
GREEN: Symbol("green")
};
Object.freeze(Colors);
const
Хранит Colors
от быть переназначены, и замораживание он предотвращает мутирует ключи и значения. Я использую символы, которые Colors.RED
не равны 0
, или что-то еще, кроме самого себя.
Есть ли проблема с этой формулировкой? Есть ли способ лучше?
(Я знаю, что этот вопрос немного повторяется, но все предыдущие вопросы и ответы довольно старые, и ES6 дает нам некоторые новые возможности.)
РЕДАКТИРОВАТЬ:
Другое решение, которое касается проблемы сериализации, но я считаю, что все еще есть проблемы с областями:
const enumValue = (name) => Object.freeze({toString: () => name});
const Colors = Object.freeze({
RED: enumValue("Colors.RED"),
BLUE: enumValue("Colors.BLUE"),
GREEN: enumValue("Colors.GREEN")
});
Используя ссылки на объекты в качестве значений, вы получаете то же предотвращение столкновений, что и символы.
источник
JSON.stringify()
. Невозможно сериализовать / десериализоватьSymbol
.Ответы:
Я не вижу никого.
Я бы свел два утверждения в одно:
Если вам не нравится шаблон, как повторяющиеся
Symbol
вызовы, вы, конечно же, можете написать вспомогательную функцию,makeEnum
которая создает то же самое из списка имен.источник
Symbol.for
это не имеет проблем кросс-Realm, однако он имеет обычную проблему столкновения с поистине глобальным пространством имен .enum => ({[Colors.RED]: "bright red", [Colors.BLUE]: "deep blue", [Colors.GREEN]: "grass green"}[enum])
).Хотя использование
Symbol
в качестве значения перечисления отлично подходит для простых случаев использования, может быть удобно присвоить свойства перечислениям. Это можно сделать, используя вObject
качестве значения перечисления, содержащего свойства.Например, мы можем дать каждому из
Colors
имя и шестнадцатеричное значение:Включение свойств в перечисление позволяет избежать необходимости писать
switch
операторы (и, возможно, забыть о новых случаях в операторах переключения при расширении перечисления). В примере также показаны свойства и типы перечисления, задокументированные с помощью аннотации перечисления JSDoc .Равенство, как и ожидалось, работает с
Colors.RED === Colors.RED
бытиемtrue
иColors.RED === Colors.BLUE
бытиемfalse
.источник
Как упоминалось выше, вы также можете написать
makeEnum()
вспомогательную функцию:Используйте это так:
источник
const makeEnum = (...lst) => Object.freeze(Object.assign({}, ...lst.map(k => ({[k]: Symbol(k)}))));
Тогда используйте это какconst colors = makeEnum("Red", "Green", "Blue")
Это мой личный подход.
источник
Проверьте, как это делает TypeScript . В основном они делают следующее:
Используйте символы, заморозьте объект, что хотите.
источник
MAP[MAP[1] = 'A'] = 1;
вместоMAP[1] = 'A'; MAP['A'] = 1;
. Я всегда слышал, что использование присваивания в качестве выражения - плохой стиль. Кроме того, какую выгоду вы получаете от зеркальных заданий?MAP[MAP[1] = 'A'] = 1;
.x
допустимым значением EnumEnum[Enum[x]] === x
. Это не решает ни одну из моих первоначальных проблем, но может быть полезно и ничего не ломает.Если вам не нужен чистый ES6 и вы можете использовать Typescript, он имеет приятное
enum
:https://www.typescriptlang.org/docs/handbook/enums.html
источник
Вы можете проверить Enumify , очень хорошую и хорошо оснащенную библиотеку для перечислений ES6.
источник
Может быть, это решение? :)
Пример:
источник
Я предпочитаю подход @ tonethar с небольшим количеством улучшений и копаний, чтобы лучше понять основы экосистемы ES6 / Node.js. На фоне серверной части забора я предпочитаю подход функционального стиля вокруг примитивов платформы, это минимизирует раздувание кода, скользкий уклон в долину управления государством в тени смерти из-за введения новых типов и увеличения удобочитаемость - делает более ясным намерение решения и алгоритм.
Решение с TDD , ES6 , Node.js , Lodash , Jest , Babel , ESLint
источник
Array.from(Object.assign(args))
абсолютно ничего не делает. Вы можете просто использовать...args
напрямую.Вот мой подход, включая некоторые вспомогательные методы
-
источник
вы также можете использовать пакет es6-enum ( https://www.npmjs.com/package/es6-enum ). Это очень просто в использовании. Смотрите пример ниже:
источник
Вот моя реализация перечисления Java в JavaScript.
Я также включил модульные тесты.
источник
Вы можете использовать ES6 Map
источник
const x = Object.freeze({key: 'value'})
вместо этого, чтобы получить что-то, что выглядит и ведет себя как enum в ES6