数组/对象作为索引

3

在jQuery的ajax请求中,我设置了回调函数来处理错误:

success: function(a) {
    if (a.error) switch (a.error) {
    case "formError":
    case "clientError":
    case "limitError":
        doErrorCorrection();
        alert("Client-sided error: " + a.errorMessage);
        break;
    case "serverError":
    case "500Error":
        doRollback();
        doTransactions();
        break;
    case "generalError":
        alert("One plus one is: " + (1+1));
    } else doActionsWith(a)
}

我想将它转换为自己的对象,例如:
var errors = {
    ...
    formError: function() {...},
    generalError: function() {...},
    ...
};

有了这个,我可以说:

success: function(a) {
    if (a.error) return errors[a.error](a.errorMessage);
    doActionsWith(a)
}

问题在于我有太多来自开关的回流,如果我要将其转换为一个对象,那就意味着同样的函数会一遍又一遍地重复。
var errors = {
    formError: function() { methodA() },
    clientError: function() { methodA() },
    limitError: function() { methodA() },
    ...
    //more if I had more reflows
};

因此,我考虑将数组/列表作为索引。我尝试设置了一个类似于以下的索引:

var arr = {
    test: 'hello world'
};

var index = ['a', 'b', 'c'];

arr[index] = 'array as index';

它起到了作用,但只是部分作用。当我通过键运行时,它们返回为字符串:

for (var key in arr) console.log(key)
//test
//a,b,c

使用对象进行相同的测试,index = {'a' = true} 只将字符串索引 object Object 设置为 数组作为索引

好的,那么数组/对象作为索引是不起作用的,我应该如何将我的开关重构为对象?


请注意,{ formError: function() { methodA() } }{ formError: methodA }是相同的。 - JJJ
我不太清楚你的问题是什么... for..in 循环在处理对象键时可以正常工作,但在处理对象本身时却不能?顺便说一下,你的第二个对象 index = { 'a' = true } 是错误的,应该是 index = { 'a': true } - Dziad Borowy
两个测试都没有通过。返回的键是字符串字面量。看起来对象键已经被规范化为字符串了。 - Dave Chen
@DaveChen 对象键总是字符串。 - Dziad Borowy
2个回答

1
当您将数组用作对象属性名称时,它们会被转换为字符串等效项,因此[1,2,3]将被用作"1,2,3";它不会像“如果值是这些值之一”那样工作。
对于您的特定问题,我会创建一个专门的错误处理程序对象,如下所示:
function ErrorHandler(map, handlers)
{
    this.map = map;
    this.handlers = handlers;
}

ErrorHandler.prototype.handle = function(a) {
    var handler = this.handlers[this.map[a.error]];

    if (handler) {
        handler(a);
    }
}

构造函数需要一个错误映射和处理函数;当调用.handle()方法时,它会查找处理程序并运行。以下是实例化的方法:
var myHandler = new ErrorHandler({
    "formError": "clientError",
    "clientError": "clientError",
    "limitError": "clientError",
    "serverError": "serverError",
    "500Error": "serverError"
    "generalError": "genericError"
}, {
    clientError: function(a) {
        doErrorCorrection();
        alert("Client-sided error: " + a.errorMessage);
    },
    serverError: function(a) {
        doRollback();
        doTransactions();
    },
    genericError: function(a) {
        alert("One plus one is: " + (1+1));
    }
});

使用它:

success: function(a) {
    if (a.error) {
        myHandler.handle(a);
    } else doActionsWith(a)
}

为了防止范围内的污染,我设计了类似于这个的东西。问题是我需要这样说:formError: function() { this.methods.clientError() } 这将会重复太多次。 - Dave Chen
@DaveChen 更新了答案以突出另一个选项。 - Ja͢ck
1
为了防止当前作用域中的污染,只需使用类似于这样的闭包:http://jsfiddle.net/slebetman/PuKUL/。不需要过多的重复。 - slebetman

1
你可以像这样维护一个对象数组:
var arr = [{ 
    msg: 'Hello World',
    val: ['a', 'b', 'c']
}, {
    msg: 'This is a dummy text.',
    val: ['d', 'e', 'f']
}];

// now perform your search
for (var obj in arr) {
    var idx = arr[obj].val.indexOf('a');
    if (idx !== -1) { // if val is found
        alert(arr[obj].msg);    // alerts "Hello World"
    }
}

我将 msg 更改为 handlerval 更改为 handles。+1 & 已接受。 - Dave Chen

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