What is the preferred syntax for defining enums in JavaScript?

What is the preferred syntax for defining enums in JavaScript? Something like:

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

// later on

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

Or is there a more preferable idiom?


Since 1.8.5 it's possible to seal and freeze the object, so define the above as:

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

or

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

and voila! JS enums.

Source

Quotes aren't needed but I kept them for consistency.


This isn't much of an answer, but I'd say that works just fine, personally

Having said that, since it doesn't matter what the values are (you've used 0, 1, 2), I'd use a meaningful string in case you ever wanted to output the current value.


UPDATE : Thanks for all the upvotes everyone, but I don't think my answer below is the best way to write enums in Javascript anymore. See my blog post for more details: Enums in Javascript.


Alerting the name is already possible:

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);
   }
}

Alternatively, you could make the values objects, so you can have the cake and eat it too:

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);
}

In Javascript, as it is a dynamic language, it is even possible to add enum values to the set later:

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

Remember, the fields of the enum (value, name and code in this example) are not needed for the identity check and are only there for convenience. Also the name of the size property itself does not need to be hardcoded, but can also be set dynamically. So supposing you only know the name for your new enum value, you can still add it without problems:

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

Of course this means that some assumptions can no longer be made (that value represents the correct order for the size for example).

Remember, in Javascript an object is just like a map or hashtable. A set of name-value pairs. You can loop through them or otherwise manipulate them without knowing much about them in advance.

EG:

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.        
  }
} 

And btw, if you are interested in namespaces, you may want to have a look at my solution for simple but powerful namespace and dependency management for javascript: Packages JS

链接地址: http://www.djcxy.com/p/2668.html

上一篇: 从C#中的枚举中获取int值

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