Использование констант в качестве индексов для ассоциативных массивов Javascript - PullRequest
18 голосов
/ 07 ноября 2010

Я хочу создать ассоциативный массив в JS, но использую константы, определенные как часть класса, как индексы.

Причина, по которой я хочу, заключается в том, чтобы пользователи класса могли использовать константы (которые определяют события) для запуска действий.

Некоторый код для иллюстрации:

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;

У меня проблемы с тем, чтобы заставить это работать.Я не слишком хорош в JS, но похоже, что независимо от того, что я делаю, массив определяется со строками, а не с константами.Есть ли способ заставить массив использовать константы?

Спасибо!

Ответы [ 2 ]

36 голосов
/ 07 ноября 2010

Проблема здесь, на самом деле, заключается в том, что вы не можете использовать значение для ключевой части при определении объекта буквально .

То есть это используетпостоянные значения, как и ожидалось:

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

Но это не сработает, как ожидалось, вместо этого используйте строку CONSTANT_A в качестве ключа:

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 есть сокращение для определения литералов объектов, где вы можете опустить двойные кавычки вокруг ключей.Выражения не могут быть использованы, поэтому CONSTANT_A не будет оцениваться.

См. Также @ ответ Кристиана ниже: ES6 / современный JS, по сути дела, то, что вы хотите, возможно.

33 голосов
/ 01 марта 2016

В ES6 вы можете использовать вычисленные значения для ключей объекта.

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

console.log(state_machine)

Это не работает ни в IE 11, ни в браузерах Safari: https://kangax.github.io/compat-table/es6/#test-object_literal_extensions_computed_properties

...