JQuery $ .extend可以用于索引吗?

时间:2012-10-16 22:56:56

标签: javascript jquery object coffeescript extend

我正在尝试扩展以下结构的Object(使用Coffeescript中的JQuery):

objectThatIsAList = {
  'List Item'      : 
    callback       :=>
      return "Some value"
  'Another item'   :
    callback       :=>
      return "Another value"
  'The final item' :
    callback       :=>
      no
}

此Object用作基于coffeescript的大型框架中下拉菜单的(动态)模型。

我用

扩展它
objectThatIsAList = $.extend {}, objectThatIsAList,  {
  'New Item' :
    callback :=>
      return "New stuff"
}

这导致像这样的对象(添加注释以显示预期结果)

objectThatIsAList = {
  'List Item'      : 
    callback       :=>
      return "Some value"
  'Another item'   :
    callback       :=>
      return "Another value"

  # this should be last
  'The final item' :
    callback       :=>
      no

  # this should not be last
  'New Item'       :
    callback       :=>
      return "New stuff"
}

显然,对象被正确扩展,但属性的顺序与构建列表的目的相关。 我更希望'Final Item'作为扩展对象的第四个而不是第三个属性

但是我的研究没有显示对$.extend方法的索引支持。有没有人成功实现过这样的功能和/或提示如何将对象属性“插入”某个位置的另一个对象?

或者有一种聪明的方法可以在$.extend之后重新定位最终项目吗?

不一定是咖啡,即使JS或Pseudocode也会有很大的帮助。

修改

这是我提出的解决方案,它扩展了遗留代码以获取数组并将它们转换为对象(在整个框架中广泛使用,并且更改原始代码会破坏大量工作代码):

# this comparison yields a data object that is passed to a method rendering a menu
if o.menu instanceof Array
  menuArrayToObj = {}
  for menuObject in o.menu
    for menuObjectProperty,menuObjectValue of menuObject
      menuArrayToObj[menuObjectProperty]=menuObjectValue if menuObjectProperty? and menuObjectValue?
  o.menu = menuArrayToObj
else o.menu 

有了这个,就可以输入一个对象或一个数组。后者很容易插入接头。

3 个答案:

答案 0 :(得分:2)

根据定义,Javascript对象无序

如果您希望维持订购,则需要Array

这方面的一个很好的例子是jQueryUI对话框对象。虽然可以按照Object选项的方式使用buttons,但如果您需要单个按钮按特定顺序,那么您必须提供数组对象。

使用此模型,您的对象将如下所示:

arrayThatIsAList = [
  { title: 'List Item', callback: ... },
  { title: 'Another Item', callback: ... },
  { title: 'New Item', callback: ... },
  { title: 'The final item', callback: ... }
];

答案 1 :(得分:1)

$.extend()用于将两个或多个对象合并为一个。 它不管理订单

如果要订购数据,则应使用对象数组(它允许您使用其索引操作数据)并使用自定义排序函数来比较对象标题:

yourArray.sort(sortfunction);

function sortfunction(yourObjectA, yourObjectB){
    //Compare yourObjectA and yourObjectB, and return -1, 0, or 1
}

答案 2 :(得分:0)

将具有第一个属性的对象放入调用$.extend的第一个参数中:

objectThatIsAList = $.extend { 
  'New Item' : 
    callback :=> 
      return "New stuff" 
}, objectThatIsAList

“不!”,你哭了,“ECMAScript规范明确地保留了未定义的属性枚举排序!”

是的,是的。有效点。 但是,所有现代ECMAScript实现都按照定义它们的顺序枚举属性。它成为事实上的标准。在这里试试:jsfiddle.net/TqfNE。我怀疑任何人都可以找到一个浏览器,它按照定义顺序以外的顺序列出属性。

因此,根据规范不能保证,但出于所有实际目的,它始终如一地工作。

但请注意,如果您开始使用整数作为属性名称,在浏览器之间获得不一致的结果。