Search code examples
javascriptconstantsassociative-array

Using constants as indices for JavaScript associative arrays


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?


Solution

  • See Kristian's answer re: ECMAScript 6/modern JavaScript, which has new syntax to make this possible.

    The below is my original answer, from the pre-modern age.


    The problem here, actually, is that you can't use a value for the key part when you're defining an object literally.

    That is to say, this uses the constant values as expected:

    var CONSTANT_A = 0, CONSTANT_B = 1;
    var state_machine = {};
    state_machine[CONSTANT_A] = "A";
    state_machine[CONSTANT_B] = "B";
    console.log(state_machine[0]); // => A
    console.log(state_machine[1]); // => B

    But this won't work as expected, instead using the string CONSTANT_A as key:

    var CONSTANT_A = 0, CONSTANT_B = 1;
    var state_machine = {
        CONSTANT_A: "A",
        CONSTANT_B: "B",
    };
    console.log(state_machine[0]); // => undefined
    console.log(state_machine["CONSTANT_A"]); // => A
    console.log(state_machine.CONSTANT_A); // => A

    JavaScript has a shorthand to define object literals where you can omit the double-quotes around keys. Expressions can't be used, so CONSTANT_A won't be evaluated.