I need to emulate enum type in Javascript and approach seems pretty straight forward:
var MyEnum = {Left = 1; Right = 2; Top = 4; Bottom = 8}
Now, in C# I could combine those values like this:
MyEnum left_right = MyEnum.Left | MyEnum.Right
and then I can test if enum has certain value:
if (left_right & MyEnum.Left == MyEnum.Left) {...}
Can I do something like that in Javascript?
In javascript you should be able to combine them as:
var left_right = MyEnum.Left | MyEnum.Right;
Then testing would be exactly as it is in your example of
if ( (left_right & MyEnum.Left) == MyEnum.Left) {...}
You just have to use the bitwise operators:
var myEnum = {
left: 1,
right: 2,
top: 4,
bottom: 8
}
var myConfig = myEnum.left | myEnum.right;
if (myConfig & myEnum.right) {
// right flag is set
}
More info:
- Understanding bitwise operations in javascript
- How to check my byte flag?
Yes, bitwise arithmetic works in Javascript. You have to be careful with it because Javascript only has the Number
data type, which is implemented as a floating-point type. But, values are converted to signed 32-bit values for bitwise operations. So as long as you don't try to use more than 31 bits, you'll be fine.
I've tried to create an example that demonstrates a common use case where one may want to use bit mask enums to control logging verbosity. It demonstrates the us of JavaScript bit-wise operations: See it on 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");
}