JavaScript,定义不可修改的枚举

时间:2013-09-26 18:04:11

标签: javascript enums unmodifiable

所以,我受到这个问题(Enums in JavaScript?)的启发,开始使用JavaScript的库插入来启用不可修改的枚举。我已经定义了一个体面的工作方法,但我想更多地充实它。

此概念使用Object.defineProperty(文档:Here

我目前的定义允许:

var obj1 = {}, obj2 = {}, obj3 = {};
// Straight declaration (normal)
obj1.Enum('RED','BLUE','GREEN');
obj1.RED    // == 0
obj1.BLUE   // == 1
obj1.GREEN  // == 2
// Buffer (padding) usage
obj2.Enum('RED','BLUE',null,undefined,'','GREEN');
obj2.RED    // == 0
obj2.BLUE   // == 1
obj2.GREEN  // == 5
// Direct offset and case-correction
obj3.Enum('RED','BLUE',10,'gReEn','burnt orange');
obj3.RED           // == 0
obj3.BLUE          // == 1
obj3.GREEN         // == 11
obj3.BURNT_ORANGE  // == 12

到目前为止我所拥有的:

var odp=Object.defineProperty;
odp(Object.prototype,'Enum', {
    value: function() {
        var ignore=[undefined,null,''], n=0, args=arguments;
        for(var i in args) {
            if(ignore.indexOf(args[i])<0) {
                if( typeof args[i]=="number") {
                    n=parseInt(args[i]);
                } else {
                    try {
                        odp(this,String(args[i]).toUpperCase().replace(" ","_"), {
                            value:parseInt(n),enumerable:true
                        });
                    } catch(e) {
                        console.warn(e.message);
                        n--;
                    }
                }
            }
            n++;
        }
        return this;
    }
});

我要添加的两件事是:

  1. 较旧的浏览器支持:因此,重新定义Object.defineProperty未定义的位置。 (我目前无法访问旧浏览器来测试可能的重新定义)
  2. 任何考虑因素我可能都错过了Enum的定义。
  3. jsFiddle:

    注意:我有odp=Object.definePropertyargs=arguments的原因是我在将JavaScript插入我的网页之前通过闭包编译器运行我的JavaScript,这样做有助于压缩。 (对于那些可能想知道的人)

1 个答案:

答案 0 :(得分:2)

  

较旧的浏览器支持:因此,重新定义Object.defineProperty未定义的位置。

你不能用当前的方法做到这一点,因为你当前的方法扩展了Object.prototype。如果你有ES5支持,那么Object.prototype 非常非常罕见,但如果没有{<1}},绝对不能 您无法创建不可枚举的属性。向Object.defineProperty添加可枚举属性会破坏所有Object.property循环。

无论如何{/ 1}}都没有理由在原型上,只需将它放在for-in(或你自己的库对象)上,然后将对象传递给它进行枚举。 / p>

  

任何考虑因素我都可能错过了Enum的定义。

在我看来,这几乎没有提供:

Enum

在ES5之前的环境中,你可以把它包装成一个可以工作的函数,而不会冻结对象,例如:

Object

当然,如果你想要自动值,你可以增强它,例如:

var obj = Object.freeze({
    "RED":   0,
    "GREEN": 1,
    "BLUE":  2
});

如果您愿意,可以将其放在function createEnum(spec) { if (Object.freeze) { spec = Object.freeze(spec); } return spec; } function createEnum(spec) { var obj = {}, n; if (Object.prototype.toString.call(spec) === "[object Array]") { // No isArray pre ES5 for (n = 0; n < spec.length; ++n) { if (spec[n] != null) { // checks for null or undefined obj[spec[n]] = n; } } } else { for (n in spec) { if (spec.hasOwnProperty(n)) { obj[n] = spec[n]; } } } if (Object.freeze) { obj = Object.freeze(obj); } return obj; } )上。


下面你说过你不想使用Object因为它使对象不可扩展。很公平,希望以后再添加枚举值。以上内容很容易适应这种情况,使用Object.prototype(如果存在),如果不存在则仅使用属性。