以下内容是否会使对象满足枚举在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
}
还是有其他方法可以做到这一点?
当前回答
这是我知道的一个旧版本,但它通过TypeScript接口实现的方式是:
var MyEnum;
(function (MyEnum) {
MyEnum[MyEnum["Foo"] = 0] = "Foo";
MyEnum[MyEnum["FooBar"] = 2] = "FooBar";
MyEnum[MyEnum["Bar"] = 1] = "Bar";
})(MyEnum|| (MyEnum= {}));
这使您能够查找返回1的MyEnum.Bar和返回“Bar”的MyEnum[1],无论声明的顺序如何。
其他回答
你可以尝试使用https://bitbucket.org/snippets/frostbane/aAjxM.
my.namespace.ColorEnum = new Enum(
"RED = 0",
"GREEN",
"BLUE"
)
它应该工作到ie8。
你可以这样做
var Enum = (function(foo) {
var EnumItem = function(item){
if(typeof item == "string"){
this.name = item;
} else {
this.name = item.name;
}
}
EnumItem.prototype = new String("DEFAULT");
EnumItem.prototype.toString = function(){
return this.name;
}
EnumItem.prototype.equals = function(item){
if(typeof item == "string"){
return this.name == item;
} else {
return this == item && this.name == item.name;
}
}
function Enum() {
this.add.apply(this, arguments);
Object.freeze(this);
}
Enum.prototype.add = function() {
for (var i in arguments) {
var enumItem = new EnumItem(arguments[i]);
this[enumItem.name] = enumItem;
}
};
Enum.prototype.toList = function() {
return Object.keys(this);
};
foo.Enum = Enum;
return Enum;
})(this);
var STATUS = new Enum("CLOSED","PENDING", { name : "CONFIRMED", ackd : true });
var STATE = new Enum("CLOSED","PENDING","CONFIRMED",{ name : "STARTED"},{ name : "PROCESSING"});
如此库中所定义。https://github.com/webmodule/foo/blob/master/foo.js#L217
完整示例https://gist.github.com/lnt/bb13a2fd63cdb8bce85fd62965a20026
你的答案太复杂了
var buildSet = function(array) {
var set = {};
for (var i in array) {
var item = array[i];
set[item] = item;
}
return set;
}
var myEnum = buildSet(['RED','GREEN','BLUE']);
// myEnum.RED == 'RED' ...etc
真的很像@Duncan上面所做的,但我不喜欢用Enum破坏全局Object函数空间,所以我写了以下内容:
function mkenum_1()
{
var o = new Object();
var c = -1;
var f = function(e, v) { Object.defineProperty(o, e, { value:v, writable:false, enumerable:true, configurable:true })};
for (i in arguments) {
var e = arguments[i];
if ((!!e) & (e.constructor == Object))
for (j in e)
f(j, (c=e[j]));
else
f(e, ++c);
}
return Object.freeze ? Object.freeze(o) : o;
}
var Sizes = mkenum_1('SMALL','MEDIUM',{LARGE: 100},'XLARGE');
console.log("MED := " + Sizes.MEDIUM);
console.log("LRG := " + Sizes.LARGE);
// Output is:
// MED := 1
// LRG := 100
@Stijin也有一个简洁的解决方案(参考他的博客),其中包括这些对象的财产。我也为此写了一些代码,接下来我会把它包括在内。
function mkenum_2(seed)
{
var p = {};
console.log("Seed := " + seed);
for (k in seed) {
var v = seed[k];
if (v instanceof Array)
p[(seed[k]=v[0])] = { value: v[0], name: v[1], code: v[2] };
else
p[v] = { value: v, name: k.toLowerCase(), code: k.substring(0,1) };
}
seed.properties = p;
return Object.freeze ? Object.freeze(seed) : seed;
}
此版本生成了一个允许友好名称转换和短代码的附加属性列表。我喜欢这个版本,因为不需要像代码那样在财产中重复数据输入。
var SizeEnum2 = mkenum_2({ SMALL: 1, MEDIUM: 2, LARGE: 3});
var SizeEnum3 = mkenum_2({ SMALL: [1, "small", "S"], MEDIUM: [2, "medium", "M"], LARGE: [3, "large", "L"] });
这两者可以组合成一个处理单元mkenum(使用enum、分配值、创建和添加属性列表)。然而,由于我今天已经在这方面花了太多时间,我将把这个组合作为练习留给亲爱的读者。
在ES7中,您可以依靠静态属性执行优雅的ENUM:
class ColorEnum {
static RED = 0 ;
static GREEN = 1;
static BLUE = 2;
}
然后
if (currentColor === ColorEnum.GREEN ) {/*-- coding --*/}
(使用类而不是文本对象)的优点是有一个父类Enum,然后所有Enum都将扩展该类。
class ColorEnum extends Enum {/*....*/}