协慌网

登录 贡献 社区

在 JavaScript 中定义枚举的首选语法是什么?

在 JavaScript 中定义枚举的首选语法是什么?就像是:

my.namespace.ColorEnum = {
    RED : 0,
    GREEN : 1,
    BLUE : 2
}

// later on

if(currentColor == my.namespace.ColorEnum.RED) {
   // whatever
}

还是有更优选的成语?

答案

由于 1.8.5 可以密封和冻结对象,因此将上面定义为:

var DaysEnum = Object.freeze({"monday":1, "tuesday":2, "wednesday":3, ...})

要么

var DaysEnum = {"monday":1, "tuesday":2, "wednesday":3, ...}
Object.freeze(DaysEnum)

瞧! JS 枚举。

但是,这并不妨碍您为变量分配不需要的值,这通常是枚举的主要目标:

let day = DaysEnum.tuesday
day = 298832342 // goes through without any errors

确保更强的类型安全性(使用枚举或其他方式)的一种方法是使用TypeScriptFlow等工具。

资源

不需要引用,但我保持它们的一致性。

这不是一个很好的答案,但我会说,个人工作得很好

话虽如此,因为值是什么并不重要(你使用了 0,1,2),我会使用一个有意义的字符串,以防你想输出当前值。

更新 :感谢大家的所有赞成,但我认为下面的答案不再是在 Javascript 中编写枚举的最佳方式。有关更多详细信息,请参阅我的博文: Javascript 中的枚举


警告名称已经成为可能:

if (currentColor == my.namespace.ColorEnum.RED) {
   // alert name of currentColor (RED: 0)
   var col = my.namespace.ColorEnum;
   for (var name in col) {
     if (col[name] == col.RED)
       alert(name);
   }
}

或者,你可以制作值对象,这样你就可以吃蛋糕了:

var SIZE = {
  SMALL : {value: 0, name: "Small", code: "S"}, 
  MEDIUM: {value: 1, name: "Medium", code: "M"}, 
  LARGE : {value: 2, name: "Large", code: "L"}
};

var currentSize = SIZE.MEDIUM;
if (currentSize == SIZE.MEDIUM) {
  // this alerts: "1: Medium"
  alert(currentSize.value + ": " + currentSize.name);
}

在 Javascript 中,因为它是一种动态语言,甚至可以在以后向集合中添加枚举值:

// Add EXTRALARGE size
SIZE.EXTRALARGE = {value: 3, name: "Extra Large", code: "XL"};

请记住,身份检查不需要枚举的字段(本例中的值,名称和代码),只是为了方便起见。此外,size 属性的名称本身不需要硬编码,但也可以动态设置。因此,假设您只知道新枚举值的名称,您仍然可以毫无问题地添加它:

// Add 'Extra Large' size, only knowing it's name
var name = "Extra Large";
SIZE[name] = {value: -1, name: name, code: "?"};

当然,这意味着不能再做出一些假设(例如,该值表示大小的正确顺序)。

请记住,在 Javascript 中,对象就像地图或哈希表。一组名称 - 值对。您可以在不事先了解它们的情况下循环遍历它们或以其他方式操纵它们。

例如:

for (var sz in SIZE) {
  // sz will be the names of the objects in SIZE, so
  // 'SMALL', 'MEDIUM', 'LARGE', 'EXTRALARGE'
  var size = SIZE[sz]; // Get the object mapped to the name in sz
  for (var prop in size) {
    // Get all the properties of the size object, iterates over
    // 'value', 'name' and 'code'. You can inspect everything this way.        
  }
}

顺便说一句,如果你对命名空间感兴趣,你可能想看看我的解决方案,为 javascript 简单但强大的命名空间和依赖管理: 包 JS