这是实现枚举的正确方法吗?

Is this a correct way of implementing an enumeration?

我正在写 的答案。

我不确定我的枚举实现是否正确。待会儿我会描述它。请检查它,并告诉我是否可以做得更好。

有问题的小原型(codepen 这里)涉及绘制棋盘和棋子。有 6 个白色和 6 个黑色棋子。对于它们中的每一个,我都需要保留其名称(如 "White Bishop")和 Unicode 代码(如 "\u2654")。所以,我定义变量 pieces 如下:(还有一块 NONE 被证明对棋盘上的空方块有用)

var pieces = {
    NONE :          {name: "None",          code: " "}, 
    WHITE_KING :    {name: "White King",    code: "\u2654"}, 
    WHITE_QUEEN :   {name: "White Queen",   code: "\u2655"}, 
    WHITE_ROOK :    {name: "White Rook",    code: "\u2656"}, 
    WHITE_BISHOP :  {name: "White Bishop",  code: "\u2657"}, 
    WHITE_KNIGHT :  {name: "White Knight",  code: "\u2658"}, 
    WHITE_POWN :    {name: "White Pown",    code: "\u2659"}, 
    BLACK_KING :    {name: "Black King",    code: "\u265A"}, 
    BLACK_QUEEN :   {name: "Black Queen",   code: "\u265B"}, 
    BLACK_ROOK :    {name: "Black Rook",    code: "\u265C"}, 
    BLACK_BISHOP :  {name: "Black Bishop",  code: "\u265D"}, 
    BLACK_KNIGHT :  {name: "Black Knight",  code: "\u265E"}, 
    BLACK_POWN :    {name: "Black Pown",    code: "\u265F"}, 
};

我将棋盘上所有棋子的分布数据保存在一个名为 board 的数组中,这是该数组的初始化:

   var board =[];

    for(var i = 0; i < boardDimension*boardDimension; i++) {
        board.push({
            x: i % boardDimension,
            y: Math.floor(i / boardDimension),
            piece: pieces.NONE
        });
    };

    board[0].piece = pieces.BLACK_ROOK
    board[1].piece = pieces.BLACK_KNIGHT
    board[2].piece = pieces.BLACK_BISHOP
    board[3].piece = pieces.BLACK_QUEEN
    board[4].piece = pieces.BLACK_KING
    board[5].piece = pieces.BLACK_BISHOP
    board[6].piece = pieces.BLACK_KNIGHT
    board[7].piece = pieces.BLACK_ROOK

    board[8].piece = pieces.BLACK_POWN
    board[9].piece = pieces.BLACK_POWN
    board[10].piece = pieces.BLACK_POWN
    board[11].piece = pieces.BLACK_POWN
    board[12].piece = pieces.BLACK_POWN
    board[13].piece = pieces.BLACK_POWN
    board[14].piece = pieces.BLACK_POWN
    board[15].piece = pieces.BLACK_POWN

    board[6*8 + 0].piece = pieces.WHITE_POWN
    board[6*8 + 1].piece = pieces.WHITE_POWN
    board[6*8 + 2].piece = pieces.WHITE_POWN
    board[6*8 + 3].piece = pieces.WHITE_POWN
    board[6*8 + 4].piece = pieces.WHITE_POWN
    board[6*8 + 5].piece = pieces.WHITE_POWN
    board[6*8 + 6].piece = pieces.WHITE_POWN
    board[6*8 + 7].piece = pieces.WHITE_POWN

    board[7*8 + 0].piece = pieces.WHITE_ROOK
    board[7*8 + 1].piece = pieces.WHITE_KNIGHT
    board[7*8 + 2].piece = pieces.WHITE_BISHOP
    board[7*8 + 3].piece = pieces.WHITE_QUEEN
    board[7*8 + 4].piece = pieces.WHITE_KING
    board[7*8 + 5].piece = pieces.WHITE_BISHOP
    board[7*8 + 6].piece = pieces.WHITE_KNIGHT
    board[7*8 + 7].piece = pieces.WHITE_ROOK

并且,在代码的深处,此数据以下列方式使用:

svg.append("text")
    .attr("x", function (d) {
        return d.x*fieldSize;
    })
    .attr("y", function (d) {
        return d.y*fieldSize;
    })
    .style("font-size", "40")
    .attr("text-anchor", "middle")
    .attr("dy", "35px")
    .attr("dx", "20px")
    .text(function (d) {
        return d.piece.code;
     })
    .append("title")
    .text(function(d) {
        return d.piece.name;
    });

我是否以正确的方式定义和使用枚举?

嗯,首先 Javascript 中没有 Enum,但你可以自己实现它,看看你所做的工作,我认为这是正确,这是一个很好的尝试。

但是如果我们关注Enum的逻辑,我们应该知道一个Enum必须是constant 和它的 元素值不应该改变 所以我们必须寻找更合适的解决方案,因为在 Javascript 中我们可以覆盖任何对象

经过一番搜索,我找到了一个Javascript方法可以提供解决方案,即Object.freeze().

所以在定义你的枚举之后你应该冻结它,所以它永远不会改变:

var pieces = {
 NONE :          {name: "None",          code: " "}, 
 WHITE_KING :    {name: "White King",    code: "\u2654"}, 
 WHITE_QUEEN :   {name: "White Queen",   code: "\u2655"}, 
 WHITE_ROOK :    {name: "White Rook",    code: "\u2656"}, 
 WHITE_BISHOP :  {name: "White Bishop",  code: "\u2657"}, 
 WHITE_KNIGHT :  {name: "White Knight",  code: "\u2658"}, 
 WHITE_POWN :    {name: "White Pown",    code: "\u2659"}, 
 BLACK_KING :    {name: "Black King",    code: "\u265A"}, 
 BLACK_QUEEN :   {name: "Black Queen",   code: "\u265B"}, 
 BLACK_ROOK :    {name: "Black Rook",    code: "\u265C"}, 
 BLACK_BISHOP :  {name: "Black Bishop",  code: "\u265D"}, 
 BLACK_KNIGHT :  {name: "Black Knight",  code: "\u265E"}, 
 BLACK_POWN :    {name: "Black Pown",    code: "\u265F"}, 
};
var frozenpieces=Object.freeze(pieces);

在这种情况下,frozenpieces 对象将始终保持不变,因此我们可以假设它是一个枚举。