JavaScript中的enum和JSON标志
我有许多C#enum,其中一些启用了标志。例如:JavaScript中的enum和JSON标志,javascript,json,enums,asp.net-web-api,Javascript,Json,Enums,Asp.net Web Api,我有许多C#enum,其中一些启用了标志。例如: [Flags] public enum MyEnum { item1 = 0x0000, item2 = 0x0008 } 我用如下方式将其克隆到JavaScript中: my.namespace.MyEnum = { ITEM1: "item1", ITEM2: "item2" } 我正在使用全局WebApi转换器将枚举映射到字符串,因为我更喜欢将字符串与REST API一起使用: config.Formatters.Jso
[Flags]
public enum MyEnum
{
item1 = 0x0000,
item2 = 0x0008
}
我用如下方式将其克隆到JavaScript中:
my.namespace.MyEnum = {
ITEM1: "item1",
ITEM2: "item2"
}
我正在使用全局WebApi转换器将枚举映射到字符串,因为我更喜欢将字符串与REST API一起使用:
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new StringEnumConverter());
问题是,如果我创建一个使用此枚举的属性,它将无法使用逐位操作(即my.namespace.MyEnum.ITEM1 | my.namespace.MyEnum.ITEM2)并获得所需的结果(“ITEM1,ITEM2”)
除了删除字符串转换器外,是否有合适的方法在JavaScript中为标志枚举实现这种DataContract+JS API?为什么不重复asp.net代码中的值
MyEnum = {
ITEM1: 0x0000,
ITEM2: 0x0008
}
alert(MyEnum.ITEM1 | MyEnum.ITEM2); // shows 8
为什么不重复asp.net代码中的值呢
MyEnum = {
ITEM1: 0x0000,
ITEM2: 0x0008
}
alert(MyEnum.ITEM1 | MyEnum.ITEM2); // shows 8
虽然我不太喜欢Javascript中的枚举,也不太喜欢这样的标志操作符,但我认为这可能与您想要的非常接近:
[my.namespace.MyEnum.ITEM1, my.namespace.MyEnum.ITEM2].join(", ") //=> "item1, item2"
或
虽然我不太喜欢Javascript中的枚举,也不太喜欢这样的标志操作符,但我认为这可能与您想要的非常接近:
[my.namespace.MyEnum.ITEM1, my.namespace.MyEnum.ITEM2].join(", ") //=> "item1, item2"
或
下面是另一种伪造操作符重载的技术。这不是我真正推荐的,但无论如何,这是一个有趣的思想实验:
var Enum = function(name) {return function() {return name;};};
var my = {}; my.namespace = {};
my.namespace.MyEnum = {
ITEM1: Enum("item1"),
ITEM2: Enum("item2")
};
var Σ = function() {
var queue = [];
var valueOf = Function.prototype.valueOf;
Function.prototype.valueOf = function() {
queue.push(this());
};
return function() {
Function.prototype.valueOf = valueOf;
return queue.join(", ");
};
};
Σ()(my.namespace.MyEnum.ITEM1 | my.namespace.MyEnum.ITEM2); //=> "item1, item2"
如果你想混合和匹配不同的操作符,这是没有用的,尽管可能会使操作更复杂,但我也不想麻烦,因为即使是在现实世界中,这也可能不适用于实际情况。这里有另一种技术,可以伪造一些操作符重载。这不是我真正推荐的,但无论如何,这是一个有趣的思想实验:
var Enum = function(name) {return function() {return name;};};
var my = {}; my.namespace = {};
my.namespace.MyEnum = {
ITEM1: Enum("item1"),
ITEM2: Enum("item2")
};
var Σ = function() {
var queue = [];
var valueOf = Function.prototype.valueOf;
Function.prototype.valueOf = function() {
queue.push(this());
};
return function() {
Function.prototype.valueOf = valueOf;
return queue.join(", ");
};
};
Σ()(my.namespace.MyEnum.ITEM1 | my.namespace.MyEnum.ITEM2); //=> "item1, item2"
如果您想混合和匹配不同的运算符,这是没有用的,尽管可能会使操作变得更复杂,但我也不想麻烦,因为即使这样也可能无法用于实际情况。原因是这意味着您需要维护枚举的逻辑(对应的数字)在客户端JS上也是如此,这是不可取的。。相反,使用我的字符串方法,如果服务器决定更改其编号方案,JS将不受影响且不受影响,这对维护更有利。@automaton:hmm。枚举使用数字,因此是单词的“num”部分。你可以搜索代币并搜索整个会员资格,但这并没有让任何事情变得更容易。写出“x.ITEM1”和“ITEM1”在语义或性能上没有什么优势,事实上,“ITEM1”在js中更短、更快、更可读。@dandavis:同意,这就是为什么我在js中大多避免枚举和大多数其他形式的字符串常量。x.ITEM1比“ITEM1”的优势是,如果服务器决定更改“item1”枚举的名称,API用户不会注意到。我们可以通过简单地更改x.ITEM1表示的字符串来维护API而不会中断。这是防止API更改的另一个屏障,以及我们使用字符串而不是原始数字的事实。@automaton:但是您不再被服务器屏蔽,因为服务器决定更改字符串“ITEM1”。JS中没有强类型,您可以通过
x.ITEM1
访问它,这一事实只是对更基本的访问x['ITEM1']
的一个修饰。因此,如果您有一些很好的理由认为服务器更可能更改“item1”而不是“item1”,那么您可能有一个理由。但如果不是这样,你就不会从Javascript中获得任何东西。原因是这意味着你还需要在客户端JS上维护枚举的逻辑(对应的数字),这是不可取的。。相反,使用我的字符串方法,如果服务器决定更改其编号方案,JS将不受影响且不受影响,这对维护更有利。@automaton:hmm。枚举使用数字,因此是单词的“num”部分。你可以搜索代币并搜索整个会员资格,但这并没有让任何事情变得更容易。写出“x.ITEM1”和“ITEM1”在语义或性能上没有什么优势,事实上,“ITEM1”在js中更短、更快、更可读。@dandavis:同意,这就是为什么我在js中大多避免枚举和大多数其他形式的字符串常量。x.ITEM1比“ITEM1”的优势是,如果服务器决定更改“item1”枚举的名称,API用户不会注意到。我们可以通过简单地更改x.ITEM1表示的字符串来维护API而不会中断。这是防止API更改的另一个屏障,以及我们使用字符串而不是原始数字的事实。@automaton:但是您不再被服务器屏蔽,因为服务器决定更改字符串“ITEM1”。JS中没有强类型,您可以通过x.ITEM1
访问它,这一事实只是对更基本的访问x['ITEM1']
的一个修饰。因此,如果您有一些很好的理由认为服务器更可能更改“item1”而不是“item1”,那么您可能有一个理由。但是如果没有,你就不会在Javascript中获得任何东西。不妨使用[].toString(),自定义方法中的额外空间对我们没有什么帮助…@dandavis:当然可以,但我更希望更明确一些。空间是原始的。不妨使用[]。toString(),自定义方法中的额外空间对我们没有什么帮助…@dandavis:当然可以,但我更希望更明确一些。空间在原来的地方。