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?
An associative array is declared or dynamically createdWe can create it by assigning a literal to a variable. var arr = { "one": 1, "two": 2, "three": 3 }; Unlike simple arrays, we use curly braces instead of square brackets. This has implicitly created a variable of type Object.
JavaScript arrays are zero-indexed: the first element of an array is at index 0 , the second is at index 1 , and so on — and the last element is at the value of the array's length property minus 1 .
JavaScript does not support associative arrays. You should use objects when you want the element names to be strings (text). You should use arrays when you want the element names to be numbers.
What is an associative array? Associative arrays are basically objects in JavaScript where indexes are replaced by user-defined keys. They do not have a length property like a normal array and cannot be traversed using a normal for loop.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With