And*_*rey 46 javascript enums flags
我需要在Javascript中模拟枚举类型,方法看起来非常简单:
var MyEnum = {Left = 1; Right = 2; Top = 4; Bottom = 8}
Run Code Online (Sandbox Code Playgroud)
现在,在C#中我可以将这些值组合起来:
MyEnum left_right = MyEnum.Left | MyEnum.Right
Run Code Online (Sandbox Code Playgroud)
然后我可以测试枚举是否具有一定的价值:
if (left_right & MyEnum.Left == MyEnum.Left) {...}
Run Code Online (Sandbox Code Playgroud)
我可以在Javascript中做类似的事情吗?
CMS*_*CMS 77
您只需使用按位运算符:
var myEnum = {
left: 1,
right: 2,
top: 4,
bottom: 8
}
var myConfig = myEnum.left | myEnum.right;
if (myConfig & myEnum.right) {
// right flag is set
}
Run Code Online (Sandbox Code Playgroud)
更多信息:
Mik*_*ark 50
在javascript中,您应该能够将它们组合为:
var left_right = MyEnum.Left | MyEnum.Right;
Run Code Online (Sandbox Code Playgroud)
然后测试就像你的例子中一样
if ( (left_right & MyEnum.Left) == MyEnum.Left) {...}
Run Code Online (Sandbox Code Playgroud)
War*_*ung 11
是的,按位算术在Javascript中有效.你必须小心它,因为Javascript只有Number数据类型,它实现为浮点类型.但是,对于按位运算,值将转换为带符号的 32位值.所以只要你不尝试使用超过31位,你就没事了.
我在打字稿中实现了:
export class FlagEnumService {
constructor(private value: number = 0) {
}
public get() {
return this.value;
}
public set(value: number): this {
this.value = value;
return this;
}
public has(key: number): boolean {
return !!(this.value & key);
}
public add(key: number): this {
this.value |= key;
return this;
}
public delete(key: number): this {
this.value &= ~key;
return this;
}
public toggle(key: number): this {
this.has(key) ? this.delete(key) : this.add(key);
return this;
}
}
Run Code Online (Sandbox Code Playgroud)
并进行澄清测试
import { FlagEnumService } from './flag-enum.service';
enum Test {
None = 0,
First = 1,
Second = 2,
Third = 4,
Four = 8
}
describe('FlagEnumService', () => {
let service: FlagEnumService;
beforeEach(() => service = new FlagEnumService());
it('should create with initial value', () => {
service = new FlagEnumService(Test.First);
expect(service.get()).toBe(Test.First);
});
it('should return true if has flag', () => {
service = new FlagEnumService(Test.First);
expect(service.has(Test.First)).toBe(true);
});
it('should return false if doesn\'t have flag', () => {
service = new FlagEnumService(Test.First);
expect(service.has(Test.Second)).toBe(false);
});
it('should add', () => {
expect(service.add(Test.First).add(Test.Second).get()).toBe(Test.First + Test.Second);
});
it('should not add the same value twice', () => {
expect(service.add(Test.First).add(Test.First).get()).toBe(Test.First);
});
it('should remove', () => {
expect(
service
.add(Test.First)
.add(Test.Second)
.delete(Test.Second)
.get()
)
.toBe(Test.First);
});
it('should return 0 when add then remove the same value', () => {
expect(service.add(Test.First).delete(Test.First).get()).toBe(0);
});
it('should not remove not added values', () => {
expect(service.add(Test.First).delete(Test.Second).get()).toBe(Test.First);
});
});
Run Code Online (Sandbox Code Playgroud)
我试图创建一个示例来演示一个常见的用例,其中可能需要使用位掩码枚举来控制日志记录详细程度.它向我们演示了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");
}
Run Code Online (Sandbox Code Playgroud)