以下内容是否会使对象满足枚举在JavaScript中的所有特性?类似于:

my.namespace.ColorEnum = {
  RED : 0,
  GREEN : 1,
  BLUE : 2
}

// later on

if(currentColor == my.namespace.ColorEnum.RED) {
  // whatever
}

还是有其他方法可以做到这一点?


当前回答

您可以使用一个简单的函数来反转键和值,当它将数字整数字符串转换为数字时,它也可以处理数组。代码小、简单,可用于此用例和其他用例。

var objInvert=函数(obj){var反转={}for(对象中的变量i){如果(i.match(/^\d+$/))i=parseInt(i,10)反转[obj[i]]=i}返回反转}var musicStyles=对象冻结(objInvert(['ROCK','SURF','METAL',“BOSSA-NOVA”、“op”、“die”]))console.log(音乐样式)

其他回答

你可以试试这个:

   var Enum = Object.freeze({
            Role: Object.freeze({ Administrator: 1, Manager: 2, Supervisor: 3 }),
            Color:Object.freeze({RED : 0, GREEN : 1, BLUE : 2 })
            });

    alert(Enum.Role.Supervisor);
    alert(Enum.Color.GREEN);
    var currentColor=0;
    if(currentColor == Enum.Color.RED) {
       alert('Its Red');
    }

这是我使用的解决方案。

function Enum() {
    this._enums = [];
    this._lookups = {};
}

Enum.prototype.getEnums = function() {
    return _enums;
}

Enum.prototype.forEach = function(callback){
    var length = this._enums.length;
    for (var i = 0; i < length; ++i){
        callback(this._enums[i]);
    }
}

Enum.prototype.addEnum = function(e) {
    this._enums.push(e);
}

Enum.prototype.getByName = function(name) {
    return this[name];
}

Enum.prototype.getByValue = function(field, value) {
    var lookup = this._lookups[field];
    if(lookup) {
        return lookup[value];
    } else {
        this._lookups[field] = ( lookup = {});
        var k = this._enums.length - 1;
        for(; k >= 0; --k) {
            var m = this._enums[k];
            var j = m[field];
            lookup[j] = m;
            if(j == value) {
                return m;
            }
        }
    }
    return null;
}

function defineEnum(definition) {
    var k;
    var e = new Enum();
    for(k in definition) {
        var j = definition[k];
        e[k] = j;
        e.addEnum(j)
    }
    return e;
}

您可以这样定义枚举:

var COLORS = defineEnum({
    RED : {
        value : 1,
        string : 'red'
    },
    GREEN : {
        value : 2,
        string : 'green'
    },
    BLUE : {
        value : 3,
        string : 'blue'
    }
});

以下是访问枚举的方式:

COLORS.BLUE.string
COLORS.BLUE.value
COLORS.getByName('BLUE').string
COLORS.getByValue('value', 1).string

COLORS.forEach(function(e){
    // do what you want with e
});

我通常使用最后两种方法从消息对象映射enum。

这种方法的一些优点:

易于声明枚举易于访问您的枚举枚举可以是复杂类型如果经常使用getByValue,Enum类具有一些关联缓存

一些缺点:

由于我保留了对枚举的引用,内存管理有些混乱仍然没有类型安全性

我认为它很容易使用。https://stackoverflow.com/a/32245370/4365315

var A = {a:11, b:22}, 
enumA = new TypeHelper(A);

if(enumA.Value === A.b || enumA.Key === "a"){ 
... 
}

var keys = enumA.getAsList();//[object, object]

//set
enumA.setType(22, false);//setType(val, isKey)

enumA.setType("a", true);

enumA.setTypeByIndex(1);

更新:

这是我的助手代码(TypeHelper)。

var助手={isEmpty:函数(obj){回来obj | | obj===null | | obj===未定义| | Array.isArray(obj)&&obj.length===0;},isObject:函数(obj){return(对象类型==“object”);},sortObjectKeys:函数(对象){return Object.keys(对象).sort(函数(a,b){c=a-b;返回c});},containsItem:函数(arr,item){if(arr&&Array.isArray(arr)){return arr.indexOf(项)>-1;}其他{返回arr==项;}},pushArray:函数(arr1,arr2){if(arr1&&arr2&&Array.isArray(arr1)){arr1.push.apply(arr1,Array.isArray(arr2)?arr2:[arr2]);}}};函数TypeHelper(){var_types=参数[0],_defTypeIndex=0,_电流类型,_值,_allKeys=助手.sortObjectKeys(_types);if(arguments.length==2){_defTypeIndex=参数[1];}对象定义属性(this{关键字:{get:函数(){return _currentType;},集合:函数(val){_currentType.setType(val,true);},可枚举:真},值:{get:函数(){返回类型[_currentType];},集合:函数(val){_value.setType(val,false);},可枚举:真}});this.getAsList=函数(键){var列表=[];_allKeys.forEach(函数(键、idx、数组){if(键和类型[key]){if(!Helper.isEmpty(keys)&&Helper.containsItem(keys,key)|| Helper.isEmpty(key)){var json={};json.Key=密钥;json.Value=_types[key];Helper.pushArray(列表,json);}}});返回列表;};this.setType=函数(值,isKey){if(!Helper.isEmpty(value)){Object.keys(_types).forEach(函数(key,idx,array){if(Helper.isObject(值)){if(value&&value.Key==Key){_currentType=键;}}else if(isKey){if(value&&value.toString()==key.toString()){_currentType=键;}}否则如果(value&&value.toString()==_types[key]){_currentType=键;}});}其他{this.setDefaultType();}return isKey_类型[_currentType]:_currentType;};this.setTypeByIndex=函数(索引){对于(变量i=0;i<_allKeys.length;i++){如果(索引==i){_currentType=_allKeys[index];打破}}};this.setDefaultType=函数(){this.setTypeByIndex(_defTypeIndex);};this.setDefaultType();}变量类型A={“-1”:“任意”,“2”:“2L”,“100”:“100L”,“200”:“200L”,“1000”:“1000升”};var enumA=新的TypeHelper(TypeA,4);document.writeln(“Key=”,enumA.Key,”,Value=“,enumA.Value,”<br>“);enumA.setType(“200L”,假);document.writeln(“Key=”,enumA.Key,”,Value=“,enumA.Value,”<br>“);enumA.setDefaultType();document.writeln(“Key=”,enumA.Key,”,Value=“,enumA.Value,”<br>“);enumA.setTypeByIndex(1);document.writeln(“Key=”,enumA.Key,”,Value=“,enumA.Value,”<br>“);document.writeln(“等于=”,(enumA.Value==TypeA[“2”]));

这是我知道的一个旧版本,但它通过TypeScript接口实现的方式是:

var MyEnum;
(function (MyEnum) {
    MyEnum[MyEnum["Foo"] = 0] = "Foo";
    MyEnum[MyEnum["FooBar"] = 2] = "FooBar";
    MyEnum[MyEnum["Bar"] = 1] = "Bar";
})(MyEnum|| (MyEnum= {}));

这使您能够查找返回1的MyEnum.Bar和返回“Bar”的MyEnum[1],无论声明的顺序如何。

这里有两种实现TypeScript枚举的不同方法。

最简单的方法是迭代一个对象,向该对象添加反向键值对。唯一的缺点是必须手动设置每个成员的值。

function _enum(list) {       
  for (var key in list) {
    list[list[key] = list[key]] = key;
  }
  return Object.freeze(list);
}

var Color = _enum({
  Red: 0,
  Green: 5,
  Blue: 2
});

// Color → {0: "Red", 2: "Blue", 5: "Green", "Red": 0, "Green": 5, "Blue": 2}
// Color.Red → 0
// Color.Green → 5
// Color.Blue → 2
// Color[5] → Green
// Color.Blue > Color.Green → false

这里有一个lodash mixin,用于使用字符串创建枚举。虽然这个版本有点复杂,但它会自动为您进行编号。本例中使用的所有lodash方法都有一个常规的JavaScript等价物,因此如果需要,可以很容易地将它们切换掉。

function enum() {
    var key, val = -1, list = {};
    _.reduce(_.toArray(arguments), function(result, kvp) {    
        kvp = kvp.split("=");
        key = _.trim(kvp[0]);
        val = _.parseInt(kvp[1]) || ++val;            
        result[result[val] = key] = val;
        return result;
    }, list);
    return Object.freeze(list);
}    

// Add enum to lodash 
_.mixin({ "enum": enum });

var Color = _.enum(
    "Red",
    "Green",
    "Blue = 5",
    "Yellow",
    "Purple = 20",
    "Gray"
);

// Color.Red → 0
// Color.Green → 1
// Color.Blue → 5
// Color.Yellow → 6
// Color.Purple → 20
// Color.Gray → 21
// Color[5] → Blue