以下内容是否会使对象满足枚举在JavaScript中的所有特性?类似于:
my.namespace.ColorEnum = {
RED : 0,
GREEN : 1,
BLUE : 2
}
// later on
if(currentColor == my.namespace.ColorEnum.RED) {
// whatever
}
还是有其他方法可以做到这一点?
以下内容是否会使对象满足枚举在JavaScript中的所有特性?类似于:
my.namespace.ColorEnum = {
RED : 0,
GREEN : 1,
BLUE : 2
}
// later on
if(currentColor == my.namespace.ColorEnum.RED) {
// whatever
}
还是有其他方法可以做到这一点?
当前回答
在ES7中,您可以依靠静态属性执行优雅的ENUM:
class ColorEnum {
static RED = 0 ;
static GREEN = 1;
static BLUE = 2;
}
然后
if (currentColor === ColorEnum.GREEN ) {/*-- coding --*/}
(使用类而不是文本对象)的优点是有一个父类Enum,然后所有Enum都将扩展该类。
class ColorEnum extends Enum {/*....*/}
其他回答
这不是一个很好的答案,但我个人认为这很好
话虽如此,因为值是什么并不重要(您使用了0、1、2),所以我会使用一个有意义的字符串,以防您想要输出当前值。
在ES7中,您可以依靠静态属性执行优雅的ENUM:
class ColorEnum {
static RED = 0 ;
static GREEN = 1;
static BLUE = 2;
}
然后
if (currentColor === ColorEnum.GREEN ) {/*-- coding --*/}
(使用类而不是文本对象)的优点是有一个父类Enum,然后所有Enum都将扩展该类。
class ColorEnum extends Enum {/*....*/}
如果您使用的是Backbone,则可以使用Backbone.Collection免费获得完整的枚举功能(按id、名称和自定义成员查找)。
// enum instance members, optional
var Color = Backbone.Model.extend({
print : function() {
console.log("I am " + this.get("name"))
}
});
// enum creation
var Colors = new Backbone.Collection([
{ id : 1, name : "Red", rgb : 0xFF0000},
{ id : 2, name : "Green" , rgb : 0x00FF00},
{ id : 3, name : "Blue" , rgb : 0x0000FF}
], {
model : Color
});
// Expose members through public fields.
Colors.each(function(color) {
Colors[color.get("name")] = color;
});
// using
Colors.Red.print()
我一直在摆弄这个,因为我喜欢我的遗珠
使用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
});
由于属性可写:false,这应该使其类型安全。
因此,您应该能够创建一个自定义对象,然后对其调用Enum()。分配的值从0开始,每项递增。
var EnumColors={};
EnumColors.Enum('RED','BLUE','GREEN','YELLOW');
EnumColors.RED; // == 0
EnumColors.BLUE; // == 1
EnumColors.GREEN; // == 2
EnumColors.YELLOW; // == 3
底线:你不能。
你可以伪造它,但你不会得到类型安全。通常,这是通过创建映射到整数值的字符串值的简单字典来完成的。例如:
var DaysEnum = {"monday":1, "tuesday":2, "wednesday":3, ...}
Document.Write("Enumerant: " + DaysEnum.tuesday);
这种方法有什么问题?您可能会意外地重新定义枚举,或者意外地具有重复的枚举值。例如:
DaysEnum.monday = 4; // whoops, monday is now thursday, too
编辑
Artur Czajka的Object.freeze呢?这难道不会阻止你将星期一设置为星期四吗油炸四方饼
当然,Object.freeze可以完全解决我投诉的问题。我想提醒大家,当我写上述内容时,Object.freeze并不存在。
现在现在它打开了一些非常有趣的可能性。
编辑2这里有一个非常好的用于创建枚举的库。
http://www.2ality.com/2011/10/enums.html
虽然它可能不适合枚举的每一种有效使用,但它需要很长的路。