带有 ES6 的 Javascript 中的枚举

新手上路,请多包涵

我正在用 Javascript 重建一个旧的 Java 项目,并意识到在 JS 中没有做枚举的好方法。

我能想到的最好的是:

 const Colors = {
    RED: Symbol("red"),
    BLUE: Symbol("blue"),
    GREEN: Symbol("green")
};
Object.freeze(Colors);

const 保持 Colors 被重新分配,冻结它可以防止改变键和值。我正在使用 Symbols,因此 Colors.RED 不等于 0 或除自身之外的任何其他内容。

这个公式有问题吗?有没有更好的办法?


(我知道这个问题有点重复,但 之前的所有问答 都已经很老了,而 ES6 给了我们一些新的能力。)


编辑:

另一个解决序列化问题的解决方案,但我相信仍然存在领域问题:

 const enumValue = (name) => Object.freeze({toString: () => name});

const Colors = Object.freeze({
    RED: enumValue("Colors.RED"),
    BLUE: enumValue("Colors.BLUE"),
    GREEN: enumValue("Colors.GREEN")
});

通过使用对象引用作为值,您可以获得与 Symbols 相同的碰撞避免。

原文由 cypherfunc 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 745
2 个回答

这个公式有问题吗?

我没有看到任何。

有没有更好的办法?

我会将这两个陈述合二为一:

 const Colors = Object.freeze({
    RED:   Symbol("red"),
    BLUE:  Symbol("blue"),
    GREEN: Symbol("green")
});

如果您不喜欢样板文件,例如重复的 Symbol 调用,您当然也可以编写一个辅助函数 makeEnum 从名称列表创建相同的东西。

原文由 Bergi 发布,翻译遵循 CC BY-SA 3.0 许可协议

在使用 Symbol 时,因为枚举值适用于简单的用例,所以可以方便地为枚举提供属性。这可以通过使用 Object 作为包含属性的枚举值来完成。

例如,我们可以给每个 Colors 一个名称和十六进制值:

 /**
 * Enum for common colors.
 * @readonly
 * @enum {{name: string, hex: string}}
 */
const Colors = Object.freeze({
  RED:   { name: "red", hex: "#f00" },
  BLUE:  { name: "blue", hex: "#00f" },
  GREEN: { name: "green", hex: "#0f0" }
});

在枚举中包含属性可以避免编写 switch 语句(并且可能在扩展枚举时忘记 switch 语句的新情况)。该示例还显示了使用 JSDoc 枚举注释 记录的枚举属性和类型。

Equality与预期合作,与 Colors.RED === Colors.RED Colors.RED === Colors.BLUE false true

原文由 Justin Emery 发布,翻译遵循 CC BY-SA 4.0 许可协议

推荐问题