使用动态变量作为多维对象的键值

3

我已经疯狂地在Stackflow和谷歌上寻找解决方案,经过几个小时后,终于决定请求帮助。

这是我的数组:

endangered = '#FFA500';
shutdown = '#FF0000';
active = '#00BB00';

// Build state array
var state = {};
state = {
        NV: {
            status: shutdown,
            name: 'Las Vegas Charter School for the Deaf',
            SchoolLink: 'http://www.lvcsd.org',
            SourceLink: 'http://www.lvrj.com/news/charter-school-for-deaf-signs-off-in-bankruptcy-141399423.html',
            ClosureDate: 'March 5, 2012',
            Comment: 'Closure due to bankruptcy. State also adopted exclusive mainstreaming approach.'
        },
        WY: {
            status: shutdown,
            name: 'Wyoming School for the Deaf',
            SchoolLink: 'http://www.wyomingdeaf.com/',
            SourceLink: 'http://trib.com/news/local/article_94be7523-5bc5-5031-97ee-9431a205cfe9.html',
            ClosureDate: '2000',
            Comment: 'School replaced by a mainstream school. State also adopted exclusive mainstreaming approach.'
        }
}

此时访问它的方式可能是这样的:

stateCode = 'NV';
currentColor = state[stateCode].status; 

这段代码会检查状态数组(state array),查找其自身数组的“NV”数组,最终查找对应状态的变量,然后引用与该状态相关的颜色。在这种情况下,关闭状态将返回"#FF0000"。

如果我按照上述方法编写代码,则会返回“未定义”的错误。但是,如果我像这样编写代码:

currentColor = state['NV'].status; 

它现在运行得非常完美。但这违背了初衷,因为它变成了静态的。我需要保持stateCode动态化,因为它基于一个函数的反馈,而且会不断地变化。

我可以像这样做:

if(stateCode === 'NV') currentColor = state['NV'].status;
if(stateCode === 'WY') currentColor = state['WY'].status;

但是它很快就会变得臃肿。必须有更好的方法来处理这个问题。有什么想法吗?


请明确您所说的“它失败并显示‘未定义’”是什么意思?这是否是控制台错误消息?如果是,请展示整个消息。 - HBP
找到了问题的原因(但没有解决方案)。这是一个变量作用域的问题。JSFiddle:http://jsfiddle.net/n7hTw/1/演示了这个问题。它应该在状态时发出警报,但它没有。 - Don Cullen
2个回答

2
顺便提一下,你正在构建的是对象而不是数组
如果你想保持代码的动态性,可以保留一个颜色对象:
var colors = {
 endangered: '#FFA500',
 shutdown: '#FF0000',
 active: '#00BB00'
};

然后使用字符串来表示状态,而不是在您的状态对象上使用变量:
var state = {};
state = {
    NV: {
        status: 'shutdown',

并根据以下方式评估您当前的颜色:

var currentColor = colors[state[stateCode].status]; 

始终在变量前加上 var,除非你想创建一个全局变量,但通常情况下,局部变量就足够了。

发生在第197行的错误是由于state['TX']返回未定义。您必须在状态对象中定义要调用的所有状态(除非您想动态分配它们,但那样您就必须这样做)。 - Beat Richartz
这绝对是一个范围问题。将以下代码添加到您的代码中:var testFunc = function () { thestatus = state[stateCode].status; alert('thestatus = '+thestatus ); } 这将无法访问状态和颜色变量。 - Don Cullen
是的,如果state[stateCode]返回未定义,则无法在其上调用状态。如果state[stateCode]返回状态对象,则可以在其上调用status。然后,这将返回一个字符串。此字符串映射到颜色对象,如下所示:colors[theStatus]。但首先,在您的代码中,state['TX']必须返回除未定义之外的其他内容,您可以通过在state对象上定义'TX'来实现。 - Beat Richartz
请查看包含您代码和我添加的内部函数的JSFiddle更新:http://jsfiddle.net/n7hTw/1/ 这就是我的代码失败的确切原因;它是作用域问题。编辑:JSFiddle引用了“NV”,它在状态对象中。 - Don Cullen
1
var 声明可以防止你的变量总是在全局范围内定义。这里有一篇关于变量作用域的优秀文章。虽然这不完全是你的问题,但除非你真的需要将某些东西放在全局范围内,否则应避免使用全局变量。 - Beat Richartz
显示剩余2条评论

1

这个结构不是一个数组,而是一个对象初始化器。无论如何,你需要像这样的东西:

var colorCodes = {
    endangered: '#FFA500',
    shutdown: '#FF0000',
    active: '#00BB00'
};

var state = {
    // What you have there
};

var stateCode = '[State Code]';
var currentColor = colorCodes[state[stateCode].status];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接