使用常量作为 Javascript 关联数组的索引

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4117214/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 10:24:40  来源:igfitidea点击:

Using constants as indices for Javascript Associative Arrays

javascriptconstantsassociative-array

提问by Edan Maor

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

我希望在 JS 中创建一个关联数组,但使用定义为类的一部分的常量作为索引。

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 JS, but it looks like no matter what I do, the array gets defined with strings and not constants. Is there any way to force the array to use the constants?

我很难让它正常工作。我对 JS 不太熟悉,但看起来无论我做什么,数组都是用字符串而不是常量定义的。有没有办法强制数组使用常量?

Thanks!

谢谢!

回答by Ashe

See @Kristian's answer below re: ES6/modern JavaScript, which has new syntax to make this possible.

请参阅下面的@Kristian 回答:ES6/现代 JavaScript,它具有使这成为可能的新语法。

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_Aas key:

但这不会按预期工作,而是使用字符串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 has a shorthand to define object literals where you can omit the double-quotes around keys. Expressions can't be used, so CONSTANT_Awon't be evaluated.

JavaScript 有一个速记来定义对象字面量,您可以在其中省略键周围的双引号。表达式不能被使用,所以CONSTANT_A不会被评估。

回答by Kristian

In ES6 you can use computed values for object keys.

在 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)

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

这在 IE 11 和 safari 浏览器中都不起作用:https: //kangax.github.io/compat-table/es6/#test-object_literal_extensions_computed_properties