Ответ 1
В javascript вы сможете объединить их как:
var left_right = MyEnum.Left | MyEnum.Right;
Тогда тестирование будет таким же, как и в вашем примере
if ( (left_right & MyEnum.Left) == MyEnum.Left) {...}
Мне нужно эмулировать тип перечисления в Javascript, и подход кажется довольно прямым:
var MyEnum = {Left = 1; Right = 2; Top = 4; Bottom = 8}
Теперь, в С#, я мог бы объединить эти значения следующим образом:
MyEnum left_right = MyEnum.Left | MyEnum.Right
а затем я могу проверить, имеет ли значение enum определенное значение:
if (left_right & MyEnum.Left == MyEnum.Left) {...}
Могу ли я сделать что-то подобное в Javascript?
В javascript вы сможете объединить их как:
var left_right = MyEnum.Left | MyEnum.Right;
Тогда тестирование будет таким же, как и в вашем примере
if ( (left_right & MyEnum.Left) == MyEnum.Left) {...}
Вам просто нужно использовать операторы bitwise:
var myEnum = {
left: 1,
right: 2,
top: 4,
bottom: 8
}
var myConfig = myEnum.left | myEnum.right;
if (myConfig & myEnum.right) {
// right flag is set
}
Дополнительная информация:
Да, побитовая арифметика работает в Javascript. Вы должны быть осторожны с ним, потому что Javascript имеет только тип данных Number
, который реализуется как тип с плавающей запятой. Но значения преобразуются в подписанные 32-битные значения для побитовых операций. Поэтому, пока вы не пытаетесь использовать более 31 бит, все будет в порядке.
Я попытался создать пример, демонстрирующий общий прецедент, когда можно использовать перечисления бит-масок для управления многословным протоколированием. Он демонстрирует нам битовые операции JavaScript: Посмотрите на JSFiddle
/*
* Demonstration of how a Flags enum can be simulated in JavaScript and
* Used to control what gets logged based on user passed value
*/
// A Flags Enum (sort-of)
var LogLevels = {
NONE: 0,
INFO: 1,
TRACE: 2,
DEBUG: 4,
WARN: 8,
ERROR: 16,
FATAL: 32
};
// Initialize
var currLogLevel = LogLevels.NONE;
// User Sets a log level
var logLevel = LogLevels.WARN;
// Convert the configured logLvel to a bit-masked enum value
switch (logLevel) {
case LogLevels.INFO:
currLogLevel = LogLevels.INFO | LogLevels.TRACE | LogLevels.DEBUG | LogLevels.WARN | LogLevels.ERROR | LogLevels.FATAL;
break;
case LogLevels.TRACE:
currLogLevel = LogLevels.TRACE | LogLevels.DEBUG | LogLevels.WARN | LogLevels.ERROR | LogLevels.FATAL;
break;
case LogLevels.DEBUG:
currLogLevel = LogLevels.DEBUG | LogLevels.WARN | LogLevels.ERROR | LogLevels.FATAL;
break;
case LogLevels.WARN:
currLogLevel = LogLevels.WARN | LogLevels.ERROR | LogLevels.FATAL;
break;
case LogLevels.ERROR:
case LogLevels.FATAL:
default:
currLogLevel = LogLevels.ERROR | LogLevels.FATAL;
}
// Example: log verbosity set to WARN, so this would NOT be logged
if ((currLogLevel & LogLevels.DEBUG) == LogLevels.DEBUG) {
console.log("log DEBUG");
}