Как гарантировать, что определение моих enum не изменится в JavaScript?
Вопрос: Выполняют ли следующие объекты все характеристики перечислений (enums) в JavaScript? Рассматриваю следующий код:
my.namespace.ColorEnum = {
RED : 0,
GREEN : 1,
BLUE : 2
}
// далее
if(currentColor == my.namespace.ColorEnum.RED) {
// какие-то действия
}
Либо есть другой способ, как я могу это реализовать?
5 ответ(ов)
Это не совсем ответ, но, на мой взгляд, это вполне нормально.
Тем не менее, раз не имеет значения, какие значения вы используете (вы применили 0, 1, 2), я бы рекомендовал использовать содержительную строку на случай, если вам когда-либо нужно будет вывести текущее значение.
Вот что нам всем нужно:
function Enum(constantsList) {
for (var i in constantsList) {
this[constantsList[i]] = i;
}
}
Теперь вы можете создавать свои перечисления:
var YesNo = new Enum(['NO', 'YES']);
var Color = new Enum(['RED', 'GREEN', 'BLUE']);
Таким образом, константы могут быть доступны обычным способом (например, YesNo.YES
, Color.GREEN
), и им назначается последовательное целочисленное значение (NO = 0
, YES = 1
; RED = 0
, GREEN = 1
, BLUE = 2
).
Вы также можете добавлять методы, используя Enum.prototype
:
Enum.prototype.values = function() {
return this.allValues;
/* чтобы это работало, нужно будет определить
this.allValues = constantsList в конструкторе */
};
Редактирование - небольшое улучшение - теперь с переменным количеством аргументов: (к сожалению, это не работает должным образом в IE :S... лучше остаться на предыдущей версии)
function Enum() {
for (var i in arguments) {
this[arguments[i]] = i;
}
}
var YesNo = new Enum('NO', 'YES');
var Color = new Enum('RED', 'GREEN', 'BLUE');
Если у вас есть дополнительные вопросы, не стесняйтесь задавать!
Я немного поигрался с этой темой, так как люблю свои перечисления (enums). =)
Используя Object.defineProperty
, я, кажется, пришел к достаточно жизнеспособному решению.
Вот jsfiddle: http://jsfiddle.net/ZV4A6/
С помощью этого метода вы сможете (в теории) вызывать и определять значения перечислений для любого объекта, не затрагивая другие его атрибуты.
Object.defineProperty(Object.prototype, 'Enum', {
value: function() {
for (i in arguments) {
Object.defineProperty(this, arguments[i], {
value: parseInt(i),
writable: false,
enumerable: true,
configurable: true
});
}
return this;
},
writable: false,
enumerable: false,
configurable: false
});
Из-за атрибута writable: false
это должно обеспечить типобезопасность.
Таким образом, вы сможете создать пользовательский объект, а затем вызвать метод Enum()
на нем. Присвоенные значения начинаются с 0 и увеличиваются на единицу для каждого элемента.
var EnumColors = {};
EnumColors.Enum('RED', 'BLUE', 'GREEN', 'YELLOW');
EnumColors.RED; // == 0
EnumColors.BLUE; // == 1
EnumColors.GREEN; // == 2
EnumColors.YELLOW; // == 3
Если у вас есть вопросы или вы хотите обсудить это решение, не стесняйтесь обращаться!
Это старый вопрос, я знаю, но в TypeScript интерфейс это реализовано следующим образом:
var MyEnum;
(function (MyEnum) {
MyEnum[MyEnum["Foo"] = 0] = "Foo";
MyEnum[MyEnum["FooBar"] = 2] = "FooBar";
MyEnum[MyEnum["Bar"] = 1] = "Bar";
})(MyEnum || (MyEnum = {}));
Это позволяет вам получать значения как напрямую через MyEnum.Bar
, который возвращает 1, так и через обратный индекс MyEnum[1]
, который возвращает "Bar", независимо от порядка объявления.
Вы можете создать объект-литерал в JavaScript, как показано в вашем примере. Вот как это выглядит:
const Modes = {
DRAGGING: 'drag',
SCALING: 'scale',
CLICKED: 'click'
};
Этот объект Modes
содержит три свойства: DRAGGING
, SCALING
и CLICKED
, каждое из которых имеет строковое значение. Вы можете использовать этот объект для управления режимами в вашей программе, обращаясь к его свойствам, например, Modes.DRAGGING
для получения строки 'drag'
.
Если вам нужно добавить новые режимы или изменить существующие, вы можете просто обновить объект, не меняя его структуру. Например:
Modes.ZOOMING = 'zoom';
Теперь Modes
будет включать также режим ZOOMING
с соответствующим значением 'zoom'
.
Где найти документацию по форматированию даты в JavaScript?
В чем разница между String.slice и String.substring?
Проверка соответствия строки регулярному выражению в JS
Существует ли ссылка на "последнюю" библиотеку jQuery в Google APIs?
Как создать диалог с кнопками "Ок" и "Отмена"