【问题标题】:Javascript Enum To Corresponding String ValueJavascript枚举到对应的字符串值
【发布时间】:2011-05-16 06:33:13
【问题描述】:

所以我在我的页面的 javascript 中有这个:

var TEST_ERROR  = {
        'SUCCESS'   :   0,
        'FAIL'      :   -1,
        'ID_ERROR'  :   -2
      };

并像这样对页面中的功能进行测试:

function test()
{
    // Get the paragraph from the DOM
    var testResultParagraph = document.getElementById('testResult');

    // Check the paragraph is valid
    if(!testResultBox)
    {
        // Update the web page
        testResultParagraph.value = TEST_ERROR.ID_ERROR;
        return TEST_ERROR.ID_ERROR;
    }

    // Something to store the results
    var testResult = TEST_ERROR.SUCCESS;

    // Test the calculation
    testResult = testCalculate()

    // Update the web page
    testResultParagraph.value = testResult;

    // The test succeeded
    return TEST_ERROR.SUCCESS;
}

testCalculate() 的结果和段落的值将是 0、-1、-2,具体取决于结果。

现在我想将它映射到一个字符串,以便段落显示“成功”、“失败”或“ID 错误”

我可以通过几种方法做到这一点:

var TEST_ERROR  = {
        'SUCCESS'   :   {VALUE : 0 , STRING: 'Success' },
        'FAIL'      :   {VALUE : -1, STRING: 'Fail'    },
        'ID_ERROR'  :   {VALUE : -2, STRING: 'Id Error'},
      };

需要修改枚举点访问器,或者

var TEST_ERROR  = {
        'SUCCESS'   :   0,
        'FAIL'      :   1,
        'ID_ERROR'  :   2
      };

var TEST_STRING = [
        'Success',
        'Fail',
        'ID Error'
      ];

这需要更改逻辑(result > TEST_ERROR.SUCCESS 看起来很奇怪!)

我的问题是如何将枚举器值映射到 Javascript 中的字符串值?我认为第二种方式是最明智的,但希望枚举器对成功和否定失败。我也喜欢第一个在对象结构中包含字符串和值的想法。

有什么想法吗?

谢谢!

马特

PS。我将在 Web Worker 中进行测试,这样页面就不会挂起,结果将被放入表格中,而不是像上面那样的段落。

PPS。我对 Javascript 编程很陌生,但在 ASM、C、C++、C# 方面做了很多工作。

【问题讨论】:

  • 感谢您的回答,我在这个项目中还很早,所以会接受答案,但不确定我现在要走哪个方向。

标签: javascript enums


【解决方案1】:

不是很理想,但在不预先计算反向字典的情况下可以获得最干净的结果(此外,如果您只有几个枚举值,这应该不是什么大问题):

function string_of_enum(enum,value) 
{
  for (var k in enum) if (enum[k] == value) return k;
  return null;
}

【讨论】:

  • 效果很好!这应该是公认的答案,适用于任何枚举,没有限制。
  • 这是我的选择,因为我既需要将数值传递回服务器,又需要将文本值显示给用户。谢谢你。
【解决方案2】:

你真的需要数值吗?如果没有,那么你可以使用这样的东西:

var TEST_ERROR  = {
    SUCCESS  : 'Success',
    FAIL     : 'Fail',
    ID_ERROR : 'ID Error'
};

【讨论】:

  • 我喜欢它,它既漂亮又简单。我可以做if(result != TEST_ERROR.SUCCESS) 并使用您的答案。让我考虑一下是否需要除 TEST_ERROR.SUCCESS 之外的任何其他传递状态。
  • 内部键和/或值会被意外修改吗?如果尝试修改,如何将它们修复为常量或引发错误?看来这是一个潜在的问题。
  • 是的,你是对的。你可以使用Object.freeze(TEST_ERROR)。我认为它不会引发修改错误,但它会忽略修改。所以目的达到了。
【解决方案3】:

你总是可以让值是特定类型的对象。

var TEST_ERROR = (function() {
  function ErrorValue(value, friendly) {
    this.value = value;
    this.friendly = friendly;
  }
  ErrorValue.prototype = {
    toString: function() { return this.friendly; },
    valueOf: function() { return this.value; }
  };
  return {
    'SUCCESS': new ErrorValue(0, 'Success'),
    'FAIL': new ErrorValue(1, 'Fail'),
    'ID_ERROR': new ErrorValue(2, 'ID error')
  };
})();

现在,当您获得该类型的值时:

var err = testFunction(whatever);

你可以通过

获取字符串值
alert(err.toString());

事实上,大多数时候您甚至不必显式调用.toString()

【讨论】:

  • 好,在.toString() 中为枚举器对象构建似乎是明智的。我刚刚开始使用这个,所以如果我需要这个而不是 LukeH 解决方案,我需要考虑一下。
【解决方案4】:

如果你是打字稿,那么你已经有了枚举的定义。否则可以直接使用 JS 版本的枚举。

var Status;
(function (Status) {
    Status[Status["New"] = 0] = "New";
    Status[Status["Submitted"] = 1] = "Submitted";
    Status[Status["Approved"] = 2] = "Approved";
    Status[Status["Rejected"] = 3] = "Rejected";
})(Status || (Status = {}));
var snew = Status.New;
console.log(snew); //This is the number
console.log(Status[snew]); //This is the string

【讨论】:

【解决方案5】:

这可能与您想要的不同,但我想分享我的答案。这是受到@LukeHconst 解决方案的启发。考虑下面的bookCategory,您会注意到我使用数字作为键。

const bookCategory = {
    "0": "Biography",
    "1": "Fiction",
    "2": "History",
    "3": "Mystery",
    "4": "Suspense",
    "5": "Thriller"
};

我这样写bookCategory 是因为如果您在 MySQL 中使用枚举列。例如,

category ENUM ('0', '1', '2', '3', '4', '5')

您需要在 JavaScript 中进行某种转换。所以我想出了这个,用法很简单:

bookCategory[book.category]

【讨论】:

    【解决方案6】:

    最好的方法是:

    export const UserLevel = Object.freeze({
       BABY: 1,
       CHILED: 2
    });
    

    为什么我们需要添加 freeze UserLevel 是 const 但我们可以更改其中的值,因此 freeze 将使其安全更改。

    【讨论】:

      【解决方案7】:

      以 Victor 的出色回答为基础,因此它适用于 TypeScript:

      enumToStr(enumeration: any, value: any): string {
        for (var k in enumeration)
          if (enumeration[k] == value)
            return <string>k;
        return null;
      }
      

      【讨论】:

        【解决方案8】:

        对于 TypeScript,有一个更简单的解决方案 (如果你坚持使用JS,请忽略我的回答):

        export enum Direction {
            none,
            left = 1,
            right = 2,
            top = 4,
            bottom = 8
        }
        
        export namespace Direction {
            export function toString(dir: Direction): string {
                return Direction[dir];
            }
        
            export function fromString(dir: string): Direction {
                return (Direction as any)[dir];
            }
        }
        
        console.log("Direction.toString(Direction.top) = " + Direction.toString(Direction.top));
        // Direction.toString(Direction.top) = top
        console.log('Direction.fromString("top") = ' + Direction.fromString("top"));
        // Direction.fromString("top") = 4
        console.log('Direction.fromString("xxx") = ' + Direction.fromString("unknown"));
        // Direction.fromString("xxx") = undefined
        
        

        因为枚举类型被编译成一个对象(字典)。 不需要循环就可以找到对应的值。

        enum Direction {
            left,
            right
        }
        

        编译成:

        {
            left: 0
            right: 1
            0: "left",
            1: "right"
        }
        

        【讨论】:

        • 那是 TypeScript。这是用 JavaScript 标记的。
        • 这实际上在 JS 中帮助了我。不知道您可以使用整数作为对象键。现在我可以使用来自Object.freeze({...}); 的“枚举”对象映射两个方向
        • 是的,这是一个关于 JavaScript 的问题,但是这个 TypeScript 脚本对我非常有用 - 谢谢!我不知道我们能做到这一点……太棒了!
        • 在我的例子中,TS 没有转译它,而是结合了:stackoverflow.com/a/63574739/5811471 它就像一个魅力。谢谢
        【解决方案9】:

        我更喜欢下面的方法。

        enum ColorEnum {
          Red,
          Green,
          Blue
        }
        console.log(ColorEnum[ColorEnum.Red]);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-11-09
          • 2011-11-02
          • 2021-11-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-03-30
          相关资源
          最近更新 更多