javascript जावास्क्रिप्ट में enums परिभाषित करने के लिए पसंदीदा वाक्यविन्यास क्या है?




(24)

मैं this दृष्टिकोण के साथ आया जो जावा में enums के बाद मॉडलिंग किया गया है। ये टाइप-सुरक्षित हैं, और इसलिए आप जांच के instanceof कर सकते हैं।

आप इस तरह के enums परिभाषित कर सकते हैं:

var Days = Enum.define("Days", ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]);

Days अब Days enum को संदर्भित करता है:

Days.Monday instanceof Days; // true

Days.Friday.name(); // "Friday"
Days.Friday.ordinal(); // 4

Days.Sunday === Days.Sunday; // true
Days.Sunday === Days.Friday; // false

Days.Sunday.toString(); // "Sunday"

Days.toString() // "Days { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday } "

Days.values().map(function(e) { return e.name(); }); //["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
Days.values()[4].name(); //"Friday"

Days.fromName("Thursday") === Days.Thursday // true
Days.fromName("Wednesday").name() // "Wednesday"
Days.Friday.fromName("Saturday").name() // "Saturday"

कार्यान्वयन:

var Enum = (function () {
    /**
     * Function to define an enum
     * @param typeName - The name of the enum.
     * @param constants - The constants on the enum. Can be an array of strings, or an object where each key is an enum
     * constant, and the values are objects that describe attributes that can be attached to the associated constant.
     */
    function define(typeName, constants) {

        /** Check Arguments **/
        if (typeof typeName === "undefined") {
            throw new TypeError("A name is required.");
        }

        if (!(constants instanceof Array) && (Object.getPrototypeOf(constants) !== Object.prototype)) {

            throw new TypeError("The constants parameter must either be an array or an object.");

        } else if ((constants instanceof Array) && constants.length === 0) {

            throw new TypeError("Need to provide at least one constant.");

        } else if ((constants instanceof Array) && !constants.reduce(function (isString, element) {
                return isString && (typeof element === "string");
            }, true)) {

            throw new TypeError("One or more elements in the constant array is not a string.");

        } else if (Object.getPrototypeOf(constants) === Object.prototype && !Object.keys(constants).reduce(function (isObject, constant) {
                return Object.getPrototypeOf(constants[constant]) === Object.prototype;
            }, true)) {

            throw new TypeError("One or more constants do not have an associated object-value.");

        }

        var isArray = (constants instanceof Array);
        var isObject = !isArray;

        /** Private sentinel-object used to guard enum constructor so that no one else can create enum instances **/
        function __() { };

        /** Dynamically define a function with the same name as the enum we want to define. **/
        var __enum = new Function(["__"],
            "return function " + typeName + "(sentinel, name, ordinal) {" +
                "if(!(sentinel instanceof __)) {" +
                    "throw new TypeError(\"Cannot instantiate an instance of " + typeName + ".\");" +
                "}" +

                "this.__name = name;" +
                "this.__ordinal = ordinal;" +
            "}"
        )(__);

        /** Private objects used to maintain enum instances for values(), and to look up enum instances for fromName() **/
        var __values = [];
        var __dict = {};

        /** Attach values() and fromName() methods to the class itself (kind of like static methods). **/
        Object.defineProperty(__enum, "values", {
            value: function () {
                return __values;
            }
        });

        Object.defineProperty(__enum, "fromName", {
            value: function (name) {
                var __constant = __dict[name]
                if (__constant) {
                    return __constant;
                } else {
                    throw new TypeError(typeName + " does not have a constant with name " + name + ".");
                }
            }
        });

        /**
         * The following methods are available to all instances of the enum. values() and fromName() need to be
         * available to each constant, and so we will attach them on the prototype. But really, they're just
         * aliases to their counterparts on the prototype.
         */
        Object.defineProperty(__enum.prototype, "values", {
            value: __enum.values
        });

        Object.defineProperty(__enum.prototype, "fromName", {
            value: __enum.fromName
        });

        Object.defineProperty(__enum.prototype, "name", {
            value: function () {
                return this.__name;
            }
        });

        Object.defineProperty(__enum.prototype, "ordinal", {
            value: function () {
                return this.__ordinal;
            }
        });

        Object.defineProperty(__enum.prototype, "valueOf", {
            value: function () {
                return this.__name;
            }
        });

        Object.defineProperty(__enum.prototype, "toString", {
            value: function () {
                return this.__name;
            }
        });

        /**
         * If constants was an array, we can the element values directly. Otherwise, we will have to use the keys
         * from the constants object.
         */
        var _constants = constants;
        if (isObject) {
            _constants = Object.keys(constants);
        }

        /** Iterate over all constants, create an instance of our enum for each one, and attach it to the enum type **/
        _constants.forEach(function (name, ordinal) {
            // Create an instance of the enum
            var __constant = new __enum(new __(), name, ordinal);

            // If constants was an object, we want to attach the provided attributes to the instance.
            if (isObject) {
                Object.keys(constants[name]).forEach(function (attr) {
                    Object.defineProperty(__constant, attr, {
                        value: constants[name][attr]
                    });
                });
            }

            // Freeze the instance so that it cannot be modified.
            Object.freeze(__constant);

            // Attach the instance using the provided name to the enum type itself.
            Object.defineProperty(__enum, name, {
                value: __constant
            });

            // Update our private objects
            __values.push(__constant);
            __dict[name] = __constant;
        });

        /** Define a friendly toString method for the enum **/
        var string = typeName + " { " + __enum.values().map(function (c) {
                return c.name();
            }).join(", ") + " } ";

        Object.defineProperty(__enum, "toString", {
            value: function () {
                return string;
            }
        });

        /** Freeze our private objects **/
        Object.freeze(__values);
        Object.freeze(__dict);

        /** Freeze the prototype on the enum and the enum itself **/
        Object.freeze(__enum.prototype);
        Object.freeze(__enum);

        /** Return the enum **/
        return __enum;
    }

    return {
        define: define
    }

})();

जावास्क्रिप्ट में enums परिभाषित करने के लिए पसंदीदा वाक्यविन्यास क्या है? कुछ इस तरह:

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

// later on

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

या क्या एक और बेहतर मुहावरे है?


आप ऐसा कुछ कर सकते हैं

function Enum(){
  this.add.apply(this,arguments);
}

Enum.prototype.add = function(){
  for (var i in arguments) {
    this[arguments[i]] = new String(arguments[i]);
  }
};
Enum.prototype.toList = function(){
  return Object.keys(this)
};

var STATUS = new Enum("CLOSED","PENDING");


var STATE = new Enum("CLOSED","PENDING");

STATE.CLOSED === STATUS.CLOSED  // false;
STATE.CLOSED === "CLOSED"  // false;
STATE.CLOSED.toString() === "CLOSED"  // true;

As defined in this library. https://github.com/webmodule/foo/blob/master/foo.js#L217


यह वह समाधान है जिसका मैं उपयोग करता हूं।

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;
}

और आप इस तरह अपने enums परिभाषित करते हैं:

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

और इस तरह आप अपने enums तक पहुंचते हैं:

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
});

मैं आमतौर पर संदेश ऑब्जेक्ट्स से मैपिंग मैम के लिए अंतिम 2 विधियों का उपयोग करता हूं।

इस दृष्टिकोण के कुछ फायदे:

  • Enums घोषित करने के लिए आसान है
  • अपने enums तक पहुंचने में आसान है
  • आपके enums जटिल प्रकार हो सकता है
  • अगर आप GetByValue का उपयोग कर रहे हैं तो एनम क्लास में कुछ सहयोगी कैशिंग हैं

कुछ नुकसान:

  • वहां कुछ गन्दा स्मृति प्रबंधन चल रहा है, क्योंकि मैं enums के संदर्भ रखता हूं
  • अभी भी कोई प्रकार की सुरक्षा नहीं है

एक त्वरित और सरल तरीका होगा:

var Colors = function(){
return {
    'WHITE':0,
    'BLACK':1,
    'RED':2,
    'GREEN':3
    }
}();

console.log(Colors.WHITE)  //this prints out "0"

Even though only static methods (and not static properties) are supported in ES2015 (see here as well, §15.2.2.2), curiously you can use the below with Babel with the es2015 preset:

class CellState {
    v: string;
    constructor(v: string) {
        this.v = v;
        Object.freeze(this);
    }
    static EMPTY       = new CellState('e');
    static OCCUPIED    = new CellState('o');
    static HIGHLIGHTED = new CellState('h');
    static values      = function(): Array<CellState> {
        const rv = [];
        rv.push(CellState.EMPTY);
        rv.push(CellState.OCCUPIED);
        rv.push(CellState.HIGHLIGHTED);
        return rv;
    }
}
Object.freeze(CellState);

I found this to be working as expected even across modules (eg importing the CellState enum from another module) and also when I import a module using Webpack.

The advantage this method has over most other answers is that you can use it alongside a static type checker (eg Flow ) and you can assert, at development time using static type checking, that your variables, parameters, etc. are of the specific CellState "enum" rather than some other enum (which would be impossible to distinguish if you used generic objects or symbols).

update

The above code has a deficiency in that it allows one to create additional objects of type CellState (even though one can't assign them to the static fields of CellState since it's frozen). Still, the below more refined code offers the following advantages:

  1. no more objects of type CellState may be created
  2. you are guaranteed that no two enum instances are assigned the same code
  3. utility method to get the enum back from a string representation
  4. the values function that returns all instances of the enum does not have to create the return value in the above, manual (and error-prone) way.

    'use strict';
    
    class Status {
    
    constructor(code, displayName = code) {
        if (Status.INSTANCES.has(code))
            throw new Error(`duplicate code value: [${code}]`);
        if (!Status.canCreateMoreInstances)
            throw new Error(`attempt to call constructor(${code}`+
           `, ${displayName}) after all static instances have been created`);
        this.code        = code;
        this.displayName = displayName;
        Object.freeze(this);
        Status.INSTANCES.set(this.code, this);
    }
    
    toString() {
        return `[code: ${this.code}, displayName: ${this.displayName}]`;
    }
    static INSTANCES   = new Map();
    static canCreateMoreInstances      = true;
    
    // the values:
    static ARCHIVED    = new Status('Archived');
    static OBSERVED    = new Status('Observed');
    static SCHEDULED   = new Status('Scheduled');
    static UNOBSERVED  = new Status('Unobserved');
    static UNTRIGGERED = new Status('Untriggered');
    
    static values      = function() {
        return Array.from(Status.INSTANCES.values());
    }
    
    static fromCode(code) {
        if (!Status.INSTANCES.has(code))
            throw new Error(`unknown code: ${code}`);
        else
            return Status.INSTANCES.get(code);
    }
    }
    
    Status.canCreateMoreInstances = false;
    Object.freeze(Status);
    exports.Status = Status;
    

मैं इसके साथ खेल रहा हूं, क्योंकि मैं अपने enums प्यार करता हूँ। =)

Object.defineProperty का उपयोग करना मुझे लगता है कि मैं कुछ हद तक व्यवहार्य समाधान के साथ आया था।

यहां एक jsfiddle है: http://jsfiddle.net/ZV4A6/

इस विधि का उपयोग करना .. आपको उस सिद्धांत के अन्य विशेषताओं को प्रभावित किए बिना, किसी भी वस्तु के लिए enum मानों को कॉल और परिभाषित करने में सक्षम होना चाहिए।

Object.defineProperty(Object.prototype,'Enum', {
    value: function() {
        for(i in arguments) {
            Object.defineProperty(this,arguments[i], {
                value:parseInt(i),
                writable:false,
                enumerable:true,
                configurable:true
            });
        }
        return this;
    },
    writable:false,
    enumerable:false,
    configurable:false
}); 

writable:false विशेषता के कारण writable:false इसे इसे सुरक्षित टाइप करना चाहिए

तो आप एक कस्टम ऑब्जेक्ट बनाने में सक्षम होना चाहिए, फिर उस पर Enum() को कॉल करें। सौंपा गया मान 0 से शुरू होता है और प्रति आइटम बढ़ता है।

var EnumColors={};
EnumColors.Enum('RED','BLUE','GREEN','YELLOW');
EnumColors.RED;    // == 0
EnumColors.BLUE;   // == 1
EnumColors.GREEN;  // == 2
EnumColors.YELLOW; // == 3

ईएस 7 में, आप स्थैतिक विशेषताओं पर निर्भर एक सुरुचिपूर्ण ENUM कर सकते हैं:

class ColorEnum  {
    static RED = 0 ;
    static GREEN = 1;
    static BLUE = 2;
}

फिर

if (currentColor === ColorEnum.GREEN ) {/*-- coding --*/}

लाभ (शाब्दिक वस्तु के बजाय वर्ग का उपयोग करने के लिए) एक अभिभावक वर्ग Enum तो आपके सभी Enums उस वर्ग को बढ़ाएंगे।

 class ColorEnum  extends Enum {/*....*/}

Simplest solution:

सर्जन करना

var Status = Object.freeze({
    "Connecting":0,
    "Ready":1,
    "Loading":2,
    "Processing": 3
});

Get Value

console.log(Status.Ready) // 1

Get Key

console.log(Object.keys(Status)[Status.Ready]) // Ready

As of writing, October 2014 - so here is a contemporary solution. Am writing the solution as a Node Module, and have included a test using Mocha and Chai, as well as underscoreJS. You can easily ignore these, and just take the Enum code if preferred.

Seen a lot of posts with overly convoluted libraries etc. The solution to getting enum support in Javascript is so simple it really isn't needed. यहां कोड है:

File: enums.js

_ = require('underscore');

var _Enum = function () {

   var keys = _.map(arguments, function (value) {
      return value;
   });
   var self = {
      keys: keys
   };
   for (var i = 0; i < arguments.length; i++) {
      self[keys[i]] = i;
   }
   return self;
};

var fileFormatEnum = Object.freeze(_Enum('CSV', 'TSV'));
var encodingEnum = Object.freeze(_Enum('UTF8', 'SHIFT_JIS'));

exports.fileFormatEnum = fileFormatEnum;
exports.encodingEnum = encodingEnum;

And a test to illustrate what it gives you:

file: enumsSpec.js

var chai = require("chai"),
    assert = chai.assert,
    expect = chai.expect,
    should = chai.should(),
    enums = require('./enums'),
    _ = require('underscore');


describe('enums', function () {

    describe('fileFormatEnum', function () {
        it('should return expected fileFormat enum declarations', function () {
            var fileFormatEnum = enums.fileFormatEnum;
            should.exist(fileFormatEnum);
            assert('{"keys":["CSV","TSV"],"CSV":0,"TSV":1}' === JSON.stringify(fileFormatEnum), 'Unexpected format');
            assert('["CSV","TSV"]' === JSON.stringify(fileFormatEnum.keys), 'Unexpected keys format');
        });
    });

    describe('encodingEnum', function () {
        it('should return expected encoding enum declarations', function () {
            var encodingEnum = enums.encodingEnum;
            should.exist(encodingEnum);
            assert('{"keys":["UTF8","SHIFT_JIS"],"UTF8":0,"SHIFT_JIS":1}' === JSON.stringify(encodingEnum), 'Unexpected format');
            assert('["UTF8","SHIFT_JIS"]' === JSON.stringify(encodingEnum.keys), 'Unexpected keys format');
        });
    });

});

As you can see, you get an Enum factory, you can get all the keys simply by calling enum.keys, and you can match the keys themselves to integer constants. And you can reuse the factory with different values, and export those generated Enums using Node's modular approach.

Once again, if you are just a casual user, or in the browser etc, just take the factory part of the code, potentially removing underscore library too if you don't wish to use it in your code.


यह एक पुराना है जिसे मैं जानता हूं, लेकिन जिस तरह से इसे टाइपस्क्रिप्ट इंटरफ़ेस के माध्यम से कार्यान्वित किया गया है वह है:

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

यह आपको MyEnum.Bar दोनों पर देखने में सक्षम बनाता है जो 1, और MyEnum[1] देता है जो घोषणा के आदेश के बावजूद "बार" देता है।


निचली पंक्ति: आप नहीं कर सकते।

आप इसे नकली बना सकते हैं, लेकिन आपको टाइप सुरक्षा नहीं मिलेगी। आम तौर पर यह पूर्णांक मानों के लिए मैप किए गए स्ट्रिंग मानों का एक सरल शब्दकोश बनाकर किया जाता है। उदाहरण के लिए:

var DaysEnum = {"monday":1, "tuesday":2, "wednesday":3, ...}

Document.Write("Enumerant: " + DaysEnum.tuesday);

इस दृष्टिकोण के साथ समस्या? आप गलती से अपने गणक को फिर से परिभाषित कर सकते हैं, या गलती से डुप्लिकेट एन्युमरेंट वैल्यू कर सकते हैं। उदाहरण के लिए:

DaysEnum.monday = 4; // whoops, monday is now thursday, too

संपादित करें

आर्टूर Czajka के ऑब्जेक्ट.फ्रीज़ के बारे में क्या? क्या वह आपको सोमवार से गुरुवार को स्थापित करने से रोकने के लिए काम नहीं करेगा? - फ्राइड क्वाड

बिल्कुल, Object.freeze जिस समस्या के बारे में शिकायत करता है उसे पूरी तरह ठीक कर देगा। मैं हर किसी को याद दिलाना चाहता हूं कि जब मैंने ऊपर लिखा था, Object.freeze वास्तव में अस्तित्व में नहीं था।

अब .... अब यह कुछ बहुत ही रोचक संभावनाएं खुलता है।

2 संपादित करें
Enums बनाने के लिए यहां एक बहुत अच्छी लाइब्रेरी है।

http://www.2ality.com/2011/10/enums.html

हालांकि यह संभवतः enums के हर वैध उपयोग फिट नहीं है, यह एक बहुत लंबा रास्ता तय करता है।


मैं जवाब पर टिप्पणी पोस्ट नहीं कर सकता, इसलिए मुझे लगता है कि मैं थ्रेड को टक्कर लूंगा क्योंकि यह Google में उच्च दिखाई देता है।

1.8.5 के बाद से ऑब्जेक्ट को सील करना और फ्रीज करना संभव है, इसलिए उपरोक्त को परिभाषित करें:

var DaysEnum = Object.freeze({"monday":1, "tuesday":2, "wednesday":3, ...})

या

var DaysEnum = {"monday":1, "tuesday":2, "wednesday":3, ...}
Object.freeze(DaysEnum)

और voila! जेएस enums;)

स्रोत: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/freeze

आईएमएचओ उद्धरण की आवश्यकता नहीं है लेकिन मैंने उन्हें स्थिरता के लिए रखा है।


var ColorEnum = {
    red: {},
    green: {},
    blue: {}
}

You don't need to make sure you don't assign duplicate numbers to different enum values this way. A new object gets instantiated and assigned to all enum values.


es7 way, (iterator, freeze), usage:

const ThreeWiseMen = new Enum('Melchior', 'Caspar', 'Balthazar')

for (let name of ThreeWiseMen)
    console.log(name)


// with a given key
let key = ThreeWiseMen.Melchior

console.log(key in ThreeWiseMen) // true (string conversion, also true: 'Melchior' in ThreeWiseMen)

for (let entry from key.enum)
     console.log(entry)


// prevent alteration (throws TypeError in strict mode)
ThreeWiseMen.Me = 'Me too!'
ThreeWiseMen.Melchior.name = 'Foo'

code:

class EnumKey {

    constructor(props) { Object.freeze(Object.assign(this, props)) }

    toString() { return this.name }

}

export class Enum {

    constructor(...keys) {

        for (let [index, key] of keys.entries()) {

            Object.defineProperty(this, key, {

                value: new EnumKey({ name:key, index, enum:this }),
                enumerable: true,

            })

        }

        Object.freeze(this)

    }

    *[Symbol.iterator]() {

        for (let key of Object.keys(this))
            yield this[key]

    }

    toString() { return [...this].join(', ') }

}

मैंने एक एनम क्लास बनाया है जो ओ (1) पर मूल्यों और नामों को ला सकता है। यह ऑब्जेक्ट ऐरे भी उत्पन्न कर सकता है जिसमें सभी नाम और मान शामिल हैं।

function Enum(obj) {
    // Names must be unique, Values do not.
    // Putting same values for different Names is risky for this implementation

    this._reserved = {
        _namesObj: {},
        _objArr: [],
        _namesArr: [],
        _valuesArr: [],
        _selectOptionsHTML: ""
    };

    for (k in obj) {
        if (obj.hasOwnProperty(k)) {
            this[k] = obj[k];
            this._reserved._namesObj[obj[k]] = k;
        }
    }
}
(function () {
    this.GetName = function (val) {
        if (typeof this._reserved._namesObj[val] === "undefined")
            return null;
        return this._reserved._namesObj[val];
    };

    this.GetValue = function (name) {
        if (typeof this[name] === "undefined")
            return null;
        return this[name];
    };

    this.GetObjArr = function () {
        if (this._reserved._objArr.length == 0) {
            var arr = [];
            for (k in this) {
                if (this.hasOwnProperty(k))
                    if (k != "_reserved")
                        arr.push({
                            Name: k,
                            Value: this[k]
                        });
            }
            this._reserved._objArr = arr;
        }
        return this._reserved._objArr;
    };

    this.GetNamesArr = function () {
        if (this._reserved._namesArr.length == 0) {
            var arr = [];
            for (k in this) {
                if (this.hasOwnProperty(k))
                    if (k != "_reserved")
                        arr.push(k);
            }
            this._reserved._namesArr = arr;
        }
        return this._reserved._namesArr;
    };

    this.GetValuesArr = function () {
        if (this._reserved._valuesArr.length == 0) {
            var arr = [];
            for (k in this) {
                if (this.hasOwnProperty(k))
                    if (k != "_reserved")
                        arr.push(this[k]);
            }
            this._reserved._valuesArr = arr;
        }
        return this._reserved._valuesArr;
    };

    this.GetSelectOptionsHTML = function () {
        if (this._reserved._selectOptionsHTML.length == 0) {
            var html = "";
            for (k in this) {
                if (this.hasOwnProperty(k))
                    if (k != "_reserved")
                        html += "<option value='" + this[k] + "'>" + k + "</option>";
            }
            this._reserved._selectOptionsHTML = html;
        }
        return this._reserved._selectOptionsHTML;
    };
}).call(Enum.prototype);

आप इसे इस तरह से जोड़ सकते हैं:

var enum1 = new Enum({
    item1: 0,
    item2: 1,
    item3: 2
});

एक मूल्य लाने के लिए (जैसे सी # में Enums):

var val2 = enum1.item2;

किसी मान के लिए नाम लाने के लिए (अलग-अलग नामों के लिए समान मान डालने पर संदिग्ध हो सकता है):

var name1 = enum1.GetName(0);  // "item1"

ऑब्जेक्ट में प्रत्येक नाम और मान के साथ सरणी प्राप्त करने के लिए:

var arr = enum1.GetObjArr();

उत्पन्न होगा:

[{ Name: "item1", Value: 0}, { ... }, ... ]

आप आसानी से एचटीएमएल चयन विकल्प भी प्राप्त कर सकते हैं:

var html = enum1.GetSelectOptionsHTML();

जो रखता है:

"<option value='0'>item1</option>..."

टाइपस्क्रिप्ट enums को लागू करने के कुछ अलग तरीके यहां दिए गए हैं।

ऑब्जेक्ट में उलटा कुंजी-मूल्य जोड़े जोड़कर, ऑब्जेक्ट पर फिर से चालू करना सबसे आसान तरीका है। एकमात्र कमी यह है कि आपको प्रत्येक सदस्य के लिए मैन्युअल रूप से मान निर्धारित करना होगा।

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


और स्ट्रिंग का उपयोग करके एक enum बनाने के लिए यहां एक lodash mixin है। हालांकि यह संस्करण थोड़ा और अधिक शामिल है, यह आपके लिए स्वचालित रूप से क्रमांकन करता है। इस उदाहरण में उपयोग की जाने वाली सभी लॉसैश विधियों में नियमित जावास्क्रिप्ट समतुल्य होता है, ताकि यदि आप चाहें तो आसानी से उन्हें बाहर कर सकते हैं।

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

आपके उत्तर बहुत जटिल हैं

var buildSet = function(array) {
  var set = {};
  for (var i in array) {
    var item = array[i];
    set[item] = item;
  }
  return set;
}

var myEnum = buildSet(['RED','GREEN','BLUE']);
// myEnum.RED == 'RED' ...etc

मैंने अभी एक एनपीएम पैकेज प्रकाशित किया है gen_enum आपको जावास्क्रिप्ट में gen_enum डेटा संरचना को जल्दी से बनाने की अनुमति देता है:

var genEnum = require('gen_enum');

var AppMode = genEnum('SIGN_UP, LOG_IN, FORGOT_PASSWORD');
var curMode = AppMode.LOG_IN;
console.log(curMode.isLogIn()); // output true 
console.log(curMode.isSignUp()); // output false 
console.log(curMode.isForgotPassword()); // output false 

इस छोटे उपकरण के बारे में एक अच्छी बात आधुनिक पर्यावरण (नोडजेस और आईई 9 + ब्राउज़र सहित) में है, लौटा हुआ एनम ऑब्जेक्ट अपरिवर्तनीय है।

अधिक जानकारी के लिए कृपया https://github.com/greenlaw110/enumjs चेकआउट https://github.com/greenlaw110/enumjs

अपडेट

मैं gen_enum पैकेज और फ़ंक्शन को constjs पैकेज में विलय करता constjs , जो अपरिवर्तनीय ऑब्जेक्ट्स, JSON स्ट्रिंग deserialization, स्ट्रिंग स्थिरांक और बिटमैप पीढ़ी आदि सहित अधिक सुविधाएं प्रदान करता है। अधिक जानकारी के लिए Checkout constjs

gen_enum से gen_enum अपग्रेड करने के लिए बस कथन बदलें

var genEnum = require('gen_enum');

सेवा मेरे

var genEnum = require('constjs').enum;

I wrote enumerationjs a very tiny library to address the issue which ensures type safety , allow enum constants to inherit from a prototype , guaranties enum constants and enum types to be immutable + many little features. It allows to refactor a lot of code and move some logic inside the enum definition. Here is an example :

var CloseEventCodes = new Enumeration("closeEventCodes", {
  CLOSE_NORMAL:          { _id: 1000, info: "Connection closed normally" },
  CLOSE_GOING_AWAY:      { _id: 1001, info: "Connection closed going away" },
  CLOSE_PROTOCOL_ERROR:  { _id: 1002, info: "Connection closed due to protocol error"  },
  CLOSE_UNSUPPORTED:     { _id: 1003, info: "Connection closed due to unsupported operation" },
  CLOSE_NO_STATUS:       { _id: 1005, info: "Connection closed with no status" },
  CLOSE_ABNORMAL:        { _id: 1006, info: "Connection closed abnormally" },
  CLOSE_TOO_LARGE:       { _id: 1009, info: "Connection closed due to too large packet" }
},{ talk: function(){
    console.log(this.info); 
  }
});


CloseEventCodes.CLOSE_TOO_LARGE.talk(); //prints "Connection closed due to too large packet"
CloseEventCodes.CLOSE_TOO_LARGE instanceof CloseEventCodes //evaluates to true

Enumeration is basically a factory.

Fully documented guide available here. उम्मीद है की यह मदद करेगा।


आप इसे आजमा सकते हैं:

   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');
    }

यह बहुत अधिक जवाब नहीं है, लेकिन मैं कहूंगा कि व्यक्तिगत रूप से ठीक काम करता है

ऐसा कहने से, चूंकि इससे कोई फर्क नहीं पड़ता कि मान क्या हैं (आपने 0, 1, 2 का उपयोग किया है), यदि आप कभी भी वर्तमान मान को आउटपुट करना चाहते हैं तो मैं एक सार्थक स्ट्रिंग का उपयोग करूंगा।


अद्यतन : सभी उपरोक्त सभी के लिए धन्यवाद, लेकिन मुझे नहीं लगता कि नीचे मेरा जवाब जावास्क्रिप्ट में enums लिखने का सबसे अच्छा तरीका है। अधिक जानकारी के लिए मेरे ब्लॉग पोस्ट देखें: जावास्क्रिप्ट में Enums

नाम को अलर्ट करना पहले से ही संभव है:

if (currentColor == my.namespace.ColorEnum.RED) {
   // alert name of currentColor (RED: 0)
   var col = my.namespace.ColorEnum;
   for (var name in col) {
     if (col[name] == col.RED)
       alert(name);
   }
}

वैकल्पिक रूप से, आप मूल्य वस्तुओं को बना सकते हैं, ताकि आप केक प्राप्त कर सकें और इसे भी खा सकें:

var SIZE = {
  SMALL : {value: 0, name: "Small", code: "S"}, 
  MEDIUM: {value: 1, name: "Medium", code: "M"}, 
  LARGE : {value: 2, name: "Large", code: "L"}
};

var currentSize = SIZE.MEDIUM;
if (currentSize == SIZE.MEDIUM) {
  // this alerts: "1: Medium"
  alert(currentSize.value + ": " + currentSize.name);
}

जावास्क्रिप्ट में, क्योंकि यह गतिशील भाषा है, बाद में सेट में enum मान जोड़ना भी संभव है:

// Add EXTRALARGE size
SIZE.EXTRALARGE = {value: 3, name: "Extra Large", code: "XL"};

याद रखें, पहचान जांच के लिए enum के फ़ील्ड (इस उदाहरण में मूल्य, नाम और कोड) की आवश्यकता नहीं है और केवल सुविधा के लिए हैं। इसके अलावा आकार की संपत्ति के नाम को हार्डकोड करने की आवश्यकता नहीं है, लेकिन गतिशील रूप से सेट भी किया जा सकता है। तो आपको लगता है कि आप केवल अपने नए एनम मूल्य के लिए नाम जानते हैं, फिर भी आप इसे बिना किसी समस्या के जोड़ सकते हैं:

// Add 'Extra Large' size, only knowing it's name
var name = "Extra Large";
SIZE[name] = {value: -1, name: name, code: "?"};

बेशक इसका मतलब है कि कुछ मान्यताओं को अब नहीं बनाया जा सकता है (वह मान उदाहरण के लिए आकार के सही क्रम का प्रतिनिधित्व करता है)।

याद रखें, जावास्क्रिप्ट में एक वस्तु एक मानचित्र या हैशटेबल की तरह है। नाम-मूल्य जोड़े का एक सेट। आप उनके माध्यम से लूप कर सकते हैं या अन्यथा उनके बारे में बहुत कुछ जानने के बिना उन्हें कुशल बना सकते हैं।

ईजी:

for (var sz in SIZE) {
  // sz will be the names of the objects in SIZE, so
  // 'SMALL', 'MEDIUM', 'LARGE', 'EXTRALARGE'
  var size = SIZE[sz]; // Get the object mapped to the name in sz
  for (var prop in size) {
    // Get all the properties of the size object, iterates over
    // 'value', 'name' and 'code'. You can inspect everything this way.        
  }
} 

और बीटीडब्ल्यू, यदि आप नेमस्पेस में दिलचस्पी रखते हैं, तो आप जावास्क्रिप्ट के लिए सरल लेकिन शक्तिशाली नेमस्पेस और निर्भरता प्रबंधन के लिए अपने समाधान को देखना चाहेंगे: पैकेज जेएस


यहां हम सभी क्या चाहते हैं:

function Enum(constantsList) {
    for (var i in constantsList) {
        this[constantsList[i]] = i;
    }
}

अब आप अपने enums बना सकते हैं:

var YesNo = new Enum(['NO', 'YES']);
var Color = new Enum(['RED', 'GREEN', 'BLUE']);

ऐसा करके, स्थिरांक को सामान्य तरीके से (YesNo.YES, Color.GREEN) में आकलित किया जा सकता है और उन्हें अनुक्रमिक int मान (NO = 0, YES = 1; RED = 0, GREEN = 1, BLUE = 2) मिलता है।

आप Enum.prototype का उपयोग करके विधियां भी जोड़ सकते हैं:

Enum.prototype.values = function() {
    return this.allValues;
    /* for the above to work, you'd need to do
            this.allValues = constantsList at the constructor */
};


संपादित करें - छोटे सुधार - अब varargs के साथ: (दुर्भाग्यवश यह IE पर ठीक से काम नहीं करता है: एस ... को पिछले संस्करण के साथ चिपकना चाहिए)

function Enum() {
    for (var i in arguments) {
        this[arguments[i]] = i;
    }
}

var YesNo = new Enum('NO', 'YES');
var Color = new Enum('RED', 'GREEN', 'BLUE');

I had done it a while ago using a mixture of __defineGetter__ and __defineSetter__ or defineProperty depending on the JS version.

Here's the enum generating function I made: https://gist.github.com/gfarrell/6716853

You'd use it like this:

var Colours = Enum('RED', 'GREEN', 'BLUE');

And it would create an immutable string:int dictionary (an enum).





enums