变量是 Enum 的实例

Man*_*eld 1 javascript instanceof

我有以下 JavaScript 代码:

function testClass() {
    this.SaveValue = function (value) {
        var isInstance = value instanceof TestEnum;

        if (!isInstance) {
            return;
        }
     }
}

TestEnum = {
    VALUE_0: 0,
    VALUE_1: 1,
    VALUE_2: 2   
}
Run Code Online (Sandbox Code Playgroud)

我通过以下方式创建该对象的实例:

$(function () {
    var a = new testClass();
    a.SaveValue(TestEnum.VALUE_1);    
});
Run Code Online (Sandbox Code Playgroud)

我想做的就是测试传递给函数的值SaveValue实际上是TestEnum. 但是,当我运行此代码时,出现以下错误:Uncaught TypeError: Expecting a function in instanceof check, but got 1

我以正确的方式处理这件事吗?我尝试了 typeof 但它只返回,number这对我来说不是特别有用。

Fel*_*ing 5

您可以将值创建为“类”的实例:

function TestEnum(value) {
    this._value = value;
}

TestEnum.prototype.valueOf = function() {
    return this._value;
}

TestEnum.prototype.toString = function() {
    return 'TestEnum_' + this._value;
}

TestEnum.VALUE_0 = new TestEnum(0);
TestEnum.VALUE_1 = new TestEnum(1);
Run Code Online (Sandbox Code Playgroud)

那么下面的方法就可以工作了:

TestEnum.VALUE_0 instanceof TestEnum
Run Code Online (Sandbox Code Playgroud)

但这也意味着您必须使用 显式访问一个值的数值.valueOf。在某些情况下,JS 会自动为您执行此操作(如5 + TestEnum.VALUE_1)。可能还需要进行覆盖toString,以便可以将值用作属性。

这是否是一个可行的解决方案实际上取决于您的用例。


或者,如果只想测试某个值是否是枚举的一部分,您可以使用一个附加属性来保存所有可能的值:

TestEnum.values = {0: true, 1: true, ...};
Run Code Online (Sandbox Code Playgroud)

然后测试它

value in TestEnum.values
// or more reliable (fails for inherited `Object` properties)
TestEnum.values.hasOwnProperty(value);
Run Code Online (Sandbox Code Playgroud)

您甚至可以自动化执行此操作:

function collectValues(obj) {
    var values = {}; // or Object.create(null) if available
    for (var prop in obj) {
        if (obj.hasOwnProperty(prop)) {
            values[obj[prop]] = true;
        }
    }
    return values;
}

TestEnum.values = collectValues(TestEnum);
Run Code Online (Sandbox Code Playgroud)

但这只能可靠地适用于原始值,并且不能区分 string"1"和 number 1