在javascript中排序键/值对集合的最佳实践

Best practice for ordering a collection of key/value pairs in javascript?

本文关键字:集合 最佳 javascript 排序      更新时间:2023-09-26

在javascript/jQuery中实现以下功能的有效(且用户友好)方法是什么?

根据文件的mime类型,应该执行回调。回调由开发人员通过提供带有可选通配符(例如text/javascript、text/*、*/*)的mime类型描述和回调本身来定义。声明的类型必须按照指定的顺序与文件的给定mime类型匹配。例如,text/plain的优先级必须高于text/*。

这里有一些想法:

使用简单对象

var handler = {
 'text/javascript' : callback0,
 'text/*' : callback1
}

将是最直观的解决方案,但订单不能保证

维护两个列表

var order = ['text/javascript', 'text/*'];
var handler = [callback0, callback1];

This is would be hard to maintain if there are more than two or three types and you are using anonymous functions as callbacks.

Adding an index by wrapping the callback into an object

var handler = {
  'text/javascript' : {index: 0, callback0},
  'text/*' : {index: 1, callback1}
};

... change thousands of index-properties when inserting an item at the beginning.

Using an array of arrays

var handler = [
  ['text/javascript', callback0],
  ['text/*', callback1]
];

This might me more userfriendly than the others, but there is no direct access for known mime-types without iterating over the elements (this would be nice-to-have).

So there are some ways to do the thing I want, but what would be the right way (and why)? Maybe someone has a pattern?

Best, Hacksteak

I would use the 'simple object' solution AND the order array form the 'maintain two lists' solution.

Iterate through the order array with a block of code that uses the handler simple object to do something that either breaks the loop or continues to the next loop iteration.

EDIT TO RESPOND TO A COMMENT

I agree with your comment. I would do something like this to make it just one variable:

var handlers = {
  handler: {
    'text/javascript': callback0,
    'text/*': callback1
  },
  order: ["text/javascript", "text/*"]
};

尽管我会为handlers变量和/或handlers.handler属性选择更好的名称。

另一条评论的回应

也许你应该修改handlers.handlerhandlers.order一次一个模拟类型:

var handlers = { handler: {}, order: [] }; // initialize as empty
// add 'text/javascript' mime type
handlers['text/javascript'] = callback0;
handlers.order.push('text/javascript');
// add 'text/*' mime type
handlers['text/*'] = callback1;
handlers.order.push('text/*');

这种方法有点重复,但将来应该很容易维护。如果需要,可以编写一个函数,向handlers.handler添加一个新属性,并向handlers.order附加一个新的mime类型。

在大多数供应商中,对象的排序似乎都是按照插入顺序进行的,除了V8,这是真的,除了数字索引。请参阅以下参考资料。

我可能不会做任何循环。我可能会这样做:

var handler = {
    text: {
        javascript: callback0,
        '*': callback1
    },
    '*' : {
        '*': callback3
    }
};
var mime = 'whatevs/whatevs'.split('/');
var callback = handler[mime[0]][mime[1]] || handler['*']['*'];
callback();

参考文献

  1. 使用for循环JavaScript对象属性和数组。。在订购很重要的时候
  2. http://code.google.com/p/v8/issues/detail?id=164