Using constants as indices for JavaScript associative arrays

Edan Maor picture Edan Maor · Nov 7, 2010 · Viewed 13.6k times · Source

I'm looking to create an associative array in JavaScript, but use constants defined as part of the class as indices.

The reason I want this is so that users of the class can use the constants (which define events) to trigger actions.

Some code to illustrate:

STATE_NORMAL = 0;
STATE_NEW_TASK_ADDED = 0;
this.curr_state = STATE_NEW_TASK_ADDED;

this.state_machine = {
    /* Prototype:
    STATE_NAME: {
        EVENT_NAME: {
            "next_state": new_state_name,
            "action": func
        }
    }
    */

    STATE_NEW_TASK_ADDED : { // I'd like this to be a constant
        this.EVENT_NEW_TASK_ADDED_AJAX : {
            "next_state": STATE_NEW_TASK_ADDED,
            "action" : function() {console.log("new task added");},
        }
    }
}

// Public data members.
// These define the various events that can happen.
this.EVENT_NEW_TASK_ADDED_AJAX = 0;
this.EVENT_NEW_TASK_ADDED_AJAX = 1;

I'm having trouble getting this to work. I'm not too great with JavaScript, but it looks like no matter what I do, the array gets defined with strings and not constants. Is there a way to force the array to use the constants?

Answer

Kristian picture Kristian · Mar 1, 2016

In ECMAScript 6 you can use computed values for object keys:

var CONSTANT_A = 0, CONSTANT_B = 1
var state_machine = {
    [CONSTANT_A]: function () {
        return 'a'
    },
    [CONSTANT_B]: function () {
        return 'b'
    }
};

console.log(state_machine)

This does not work in Internet Explorer 11 nor in Safari browsers: https://kangax.github.io/compat-table/es6/#test-object_literal_extensions_computed_properties