Enumerated
What's Enumerated?
A simple, lightweight, easy-to-use and high performance implementation of Enum type for JavaScript. Enumerated uses lookup tables and bit operators internally, so is blazingly fast and also provides a friendly interface to reduce the time you spend on exploring and integrating the module. It's really lightweight - ~420 sloc excluding comments - but contains all the usual features you need and works in modern browsers (IE8+) too.
Usage
var Enum = var colors = 'red' 'green' 'blue'var selectedColors = colorsred | colorsblue colors // [ 'red', 'blue' ] var numbers = var selectedNumbers = numbersfour | numberstwo numbers // [ 2, 4 ] selectedNumbers |= numbersfive // extend selectedNumbers with another value numbers // [ 'two', 'four', 'five' ] selectedNumbers ^= numberstwo // remove one item from selectedNumbers numbers // [ 4, 5 ] selectedNumbers ^= numbersfive | numbersfour // remove two items in one step numbers // [] // not flaggable enum var states = var selectedState = statesprocessing states // 'processing' var selectedStates = statesprocessing | statespending try statescatchex // throws "Error: This enum allows only one single choice." // make it case insensitive var days = days // { key: 'monday', value: 'Monday' }days // { key: 'friday', value: 'Friday' } // items will be accessible lowercased with the dot or index operator if ignoreCase option is set to truevar selectedDays = dayssaturday | days'sunday' // ...
If you don't want to require Enumerated again and again in different modules, but instead only once in the main module, do the following:
global = true // after that point Enum constructor has been exposed to the global context, // so feel free to use it anywhere var animals = // ...
Examples of comparisons:
var foodList = 'pizza' 'hamburger' 'macaroni' 'ketchup' food = var dinner = foodpizza | foodketchup Enum // trueEnum // false food // truefood // false dinner === foodketchup | foodpizza // truedinner === foodketchup | foodhamburger // falsedinner === foodpizza // false var food2 = food == food2 // false, since object is a reference type foodpizza === food2pizza // true, because under the hood Enum uses simple integers to mark items food instanceof Enum // truefoodpizza instanceof Enum // falsetypeof food === 'object' // truetypeof foodpizza === 'number' // true
Supported constructors:
var a = b = // equivalent with the previous c = a: 1 b: 2 c: 3 // new operator is optional d = // you can pass an object containing the desired options as the last argument e = // usually the second argument will be the last :)
Examples of useful Enum instance members:
var fruitNames = apple: 'red' orange: 'orange' grape: 'green' banana: 'yellow' pineapple: 'brown' fruits = selected = fruitsapple | fruitsbanana fruits // 'red', because it returns the first selected itemfruits // [ 'red', 'yellow' ]fruits // 'apple'fruits // [ 'apple', 'banana' ] fruits // { key: 'grape', value: 'green' }fruits // { key: 'banana', value: 'yellow' } fruits // 'green'fruits // [ 'red', 'brown' ]fruits // 'banana'fruits // [ 'orange', 'grape' ], note that you also can pass an array as well to all the member functions expecting multiple parametersfruits // truefruits // falsefruits // falsefruitslength // 5fruitskeys // [ 'apple', 'orange', 'grape', 'banana', 'pineapple' ]fruitsvalues // [ 'red', 'orange', 'green', 'yellow', 'brown' ]fruitsitems /* [ { key: 'apple', value: 'red' }, { key: 'orange', value: 'orange' }, { key: 'grape', value: 'green' }, { key: 'banana', value: 'yellow' }, { key: 'pineapple', value: 'brown' }] */ fruits // { descriptor: { apple: 'red', orange: 'orange', grape: 'green', banana: 'yellow', pineapple: 'brown' }, options: { single: false, ignoreCase: false } }fruits // [ 'red', 'yellow' ] JSON // '{"descriptor":{"apple":"red","orange":"orange","grape":"green","banana":"yellow","pineapple":"brown"},"options":{"single":false,"ignoreCase":false}}' fruits === selected // true console /* Enum({ "apple": "red", "orange": "orange", "grape": "green", "banana": "yellow", "pineapple": "brown"}) */
Examples of useful Enum "static" members:
var fruits = Enum Enumglobal = true // set it true to expose Enum constructor into the global context Enum // trueEnum // falseEnum // trueEnum // false Enum // trueEnum // falseEnum // falseEnum // true EnumMAX_LENGTH // 31 or 63, the maximum count of items in an Enum instance. depends on the integer size of the system
And there is some extra sugar:
// for non-flaggable enums you can use the language's built-in switch statement var state = current = statepending // unfortunately you can't do the same with flagged enums,// but Enumerated is shipped with a handy helper method var fruits = likedFruits = fruitsapple | fruitsstrawberry | fruitsbanana { console} fruits /* output: user likes appleuser likes strawberryuser likes banana */
Note: Proper examples will be added soon to the examples folder.
Installation
With npm:
npm install --save enumerated
With git:
git clone git://github.com/schwarzkopfb/enumerated.git
cd enumerated
npm test
Browser usage
If you want to use Enumerated in a browser, just download and include enumerated.min.js in your front-end project. Don't worry, it weights only about 5 kB.
Documentation
The complete documentation with examples for all the instance and static members can be found here.
AMD (Requirejs) support
It's supported to load Enumerated with a module loader that follows the AMD pattern, like the deservedly popular Requirejs.
Unit tests
The project is entirely covered with unit tests. Of course you can npm test
to run them in Node.js environment or click here if you're curious about the results in a web browser.
Benchmark
Performance is important, so I wrote a simple benchmark for the project. The results on my MacBook Pro (Mid 2010) are the following:
- 50000000 get() calls performed in 1.36 seconds (36764705.88 ops/sec)
- 50000000 valueOf() calls performed in 2.88 seconds (17361111.11 ops/sec)
- 50000000 valuesOf() calls performed in 9.27 seconds (5393743.26 ops/sec)
- 1000000 fromValues() calls performed in 3.84 seconds (260416.67 ops/sec)
- 1000000 valuesByKeys() calls performed in 3.90 seconds (256410.26 ops/sec)
- 100000 constructor calls performed in 5.77 seconds (17331.02 ops/sec)
In the light of the results, the overhead compared to more primitive solutions is negligible.
You can run the benchmark on your machine with the following command:
npm run benchmark