以下内容是否会使对象满足枚举在JavaScript中的所有特性?类似于:

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

// later on

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

还是有其他方法可以做到这一点?


当前回答

您只需要使用object.freeze(<your_object>)创建一个不可变的对象:

export const ColorEnum = Object.freeze({
    // you can only change the property values here
    // in the object declaration like in the Java enumaration
    RED: 0,
    GREEN: 1,
    BLUE: 2,
});

ColorEnum.RED = 22    // assigning here will throw an error
ColorEnum.VIOLET = 45 // even adding a new property will throw an error

其他回答

一种快速而简单的方法是:

var Colors = function(){
return {
    'WHITE':0,
    'BLACK':1,
    'RED':2,
    'GREEN':3
    }
}();

console.log(Colors.WHITE)  //this prints out "0"

我不久前使用了__defineGetter__和__defineSetter__或defineProperty的组合,具体取决于JS版本。

下面是我制作的枚举生成函数:https://gist.github.com/gfarrell/6716853

你可以这样使用:

var Colours = Enum('RED', 'GREEN', 'BLUE');

它将创建一个不可变的字符串:int字典(一个枚举)。

更新05.11.2020:修改为包含静态字段和方法,以更接近地复制“true”枚举行为。

是否有人尝试过使用包含私有字段和“get”访问器的类执行此操作?我意识到私有类字段目前仍处于实验阶段,但它似乎可以用于创建具有不可变字段/财产的类。浏览器支持也不错。唯一不支持它的“主要”浏览器是Firefox(我相信他们很快就会支持)和IE(谁在乎)。

免责声明:我不是一个开发者。我只是在寻找这个问题的答案,并开始思考我有时如何通过创建带有私有字段和受限属性访问器的类来在C#中创建“增强”枚举。

样本类别

class Sizes {
    // Private Fields
    static #_SMALL = 0;
    static #_MEDIUM = 1;
    static #_LARGE = 2;

    // Accessors for "get" functions only (no "set" functions)
    static get SMALL() { return this.#_SMALL; }
    static get MEDIUM() { return this.#_MEDIUM; }
    static get LARGE() { return this.#_LARGE; }
}

现在您应该可以直接调用enums。

Sizes.SMALL; // 0
Sizes.MEDIUM; // 1
Sizes.LARGE; // 2

使用私有字段和有限访问器的组合意味着枚举值得到了很好的保护。

Sizes.SMALL = 10 // Sizes.SMALL is still 0
Sizes._SMALL = 10 // Sizes.SMALL is still 0
Sizes.#_SMALL = 10 // Sizes.SMALL is still 0

您可以使用Object.protype.hasOwnProperty()

变量findInEnum,颜色枚举={红色:0,绿色:1,蓝色:2};//稍后findInEnum=函数(enumKey){if(colorEnum.hasOwnProperty(enumKey)){return enumKey+“值:”+colorEnum[nenumKey]}}警报(findInEnum(“蓝色”))

在大多数现代浏览器中,有一种符号基元数据类型,可用于创建枚举。它将确保枚举的类型安全,因为JavaScript保证每个符号值都是唯一的,即symbol()!=符号()。例如:

const COLOR = Object.freeze({RED: Symbol(), BLUE: Symbol()});

为了简化调试,可以向枚举值添加描述:

const COLOR = Object.freeze({RED: Symbol("RED"), BLUE: Symbol("BLUE")});

Plunker演示

在GitHub上,您可以找到一个包装器,它简化了初始化枚举所需的代码:

const color = new Enum("RED", "BLUE")

color.RED.toString() // Symbol(RED)
color.getName(color.RED) // RED
color.size // 2
color.values() // Symbol(RED), Symbol(BLUE)
color.toString() // RED,BLUE