2012-11-27 37 views
0

我已经设置了我的问题的一个例子的jsfiddle:Example排序顺序不一致对象

鉴于这个网站:

<select id="drop1" data-jsdrop-data="countries"></select> 
<select id="drop2" data-jsdrop-data="countries2"></select>​ 

而且下面的JavaScript:

var countries = {"1" : "Albania", "5" : "Australia","2": "United Arab Emerates"}; 
var countries2 = {"AL" : "Albania", "AU" : "Australia", "AE" : "United Arab Emerates"}; 


function loadJSOptions(selector, list) { 
    $.each(list, function (key, value) { 
     $(selector).append($("<option></option>").val(key).html(value)); 
    } 
}); 

$(document).ready(function() { 
    $('select[data-jsdrop-data]').each(function() { 
     var selector = $(this); 
     var listname = selector.attr("data-jsdrop-data"); 
     var listvalue = null; 
     eval("listvalue = " + listname + ";"); 
     loadJSOptions(selector, listvalue); 
    }); 
}); 

任何人都可以向我解释为什么带有Alpha键的列表根据输入的顺序列出,而列表中的数字键得到排序基于关键?如果你看看jsFiddle结果,你会看到drop1显示阿尔巴尼亚,阿拉伯联合酋长国Emerates,澳大利亚,而drop2显示阿尔巴尼亚,澳大利亚,阿拉伯联合酋长国Emerates。

感谢您的帮助。

+2

对象键没有秩序,他们只是。 – Bergi

+0

你不能依赖对象键以任何特定的顺序。如果顺序很重要,请使用数组。 –

+1

请不要使用'eval',而是使用'eval',而不是数组或其他东西 - 对象 – Bergi

回答

1

对象属性没有排序,如果枚举它们,则顺序是实现定义的。它们通常是按照对象文字被解析的顺序存储的,但是你不能依赖它。例如,数字键(如countries1)似乎在您的浏览器中排序。

如果你需要一个明确的顺序,使用数组(与数字键的对象),并重复他们:

var lists = { 
    countries1: [ 
     {key:"1", val:"Albania"}, 
     {key:"5", val:"Australia"}, 
     {key:"2", val:"United Arab Emerates"} 
    ], 
    countries2: [ 
     {key:"AL", val:"Albania"}, 
     {key:"AU", val:"Australia"}, 
     {key:"AE", val:"United Arab Emerates"} 
    ] 
}; 

$(document).ready(function() { 
    $('select[data-jsdrop-data]').each(function() { 
     var $this = $(this), 
      listname = $this.attr("data-jsdrop-data"), 
      list = lists[listname]; // don't use eval! 
     for (var i=0; i<list.length; i++) { 
      var item = list[i]; 
      $this.append($("<option>").val(item.key).text(item.value)); 
     } 
    }); 
}); 

一个for循环更快,比$.each更直观。当你不确切地知道它做什么以及什么时候需要它时,请不要使用它。

+0

有没有办法让我的列表从一个变量没有eval,没有我所有的列表必须绑定到一个共同的列表数组? – RHarris

+0

感谢您的留言。使用对象数组保持选项按照定义的顺序......这正是我所追求的。 – RHarris

+0

@RHarris:不是,虽然你可以将变量放入列表数组而不是文字。但是,你为什么要列出不同的变量? – Bergi

0

我相信,如果你有一个对象上的数值属性,即jQuery.each()将需要使用的属性阵列类型的接入(即countries[1]countries[2]countries[5])。因此,它将以数字索引顺序迭代。

+0

编号['jQuery.each'](https://github.com/jquery/jquery/blob/master/src/core.js#L584)检查'length' propery(不在函数对象上)并迭代对象数组 - 如果它不是未定义的。 – Bergi

0

使用jQuery的$.each默认为for(a in b)不保证顺序。这就是为什么你看到订单看起来没有顺序或意外。

0

您可以更有效地建立很多的选项使用:

$('select[data-jsdrop-data]').each(function() { 
    var list = window[this.getAttribute('data-jsdrop-data')]; 
    var i = 0; 
    for (var p in list) { 
     this.options[i++] = new Option(p, list[p]); 
    } 
});