javascript - node enum




使用ES6在Javascript中枚舉 (7)

這個配方有問題嗎?

我沒有看到任何。

有沒有更好的辦法?

我將這兩個陳述合併為一個:

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

如果您不喜歡樣板文件,就像重複的 Symbol 調用一樣,您當然也可以編寫一個幫助函數 makeEnum ,它從名稱列表中創建相同的東西。

我正在用Javascript重建一個舊的Java項目,並意識到在JS中沒有好的方法來做枚舉。

我能想到的最好的是:

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

const 使 Colors 不被重新分配,並且凍結它可以防止改變鍵和值。 我正在使用符號,因此 Colors.RED 不等於 0 ,或者除了它本身之外的任何其他內容。

這個配方有問題嗎? 有沒有更好的辦法?

(我知道這個問題有點重複,但 以前的Q / As 都很老了,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相同的衝突避免。


也許這個解決方案 :)

function createEnum (array) {
  return Object.freeze(array
    .reduce((obj, item) => {
      if (typeof item === 'string') {
        obj[item] = Symbol(item)
      }
      return obj
    }, {}))
}

你可以使用ES6 Map

const colors = new Map([
  ['RED', 'red'],
  ['BLUE', 'blue'],
  ['GREEN', 'green']
]);

console.log(colors.get('RED'));

如上所述,您還可以編寫一個 makeEnum() 輔助函數:

function makeEnum(arr){
    let obj = {};
    for (let val of arr){
        obj[val] = Symbol(val);
    }
    return Object.freeze(obj);
}

像這樣使用它:

const Colors = makeEnum(["red","green","blue"]);
let startColor = Colors.red; 
console.log(startColor); // Symbol(red)

if(startColor == Colors.red){
    console.log("Do red things");
}else{
    console.log("Do non-red things");
}

您可以查看 Enumify ,這是一個非常好的,功能齊全的ES6枚舉庫。


檢查 TypeScript是如何做到的 。 基本上他們做了以下事情:

const MAP = {};

MAP[MAP[1] = 'A'] = 1;
MAP[MAP[2] = 'B'] = 2;

MAP['A'] // 1
MAP[1] // A

使用符號,凍結對象,無論你想要什麼。


雖然使用 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 語句(並且可能在枚舉枚舉時忘記新的case語句到switch語句)。 該示例還顯示了使用 JSDoc枚舉註釋 記錄的枚舉屬性和類型。

Equality按預期使用 Colors.RED === Colors.REDtrue ,而 Colors.RED === Colors.BLUEfalse





symbols