Google Chrome: JavaScript associative arrays, evaluated out of sequence

限于喜欢 提交于 2019-11-28 01:56:03

Think of an associative array as a paper sack into which all the key-value pairs are placed. As you reach your hand into the sack to look at the pairs (such as with the for...in loop), the order that you encounter them is for all practical purposes random.

If you want to see them in a specific order, you'll need to extract the keys into an array and sort it. Then walk across the array, using the keys you encounter to index into the associative array.

The order in which elements are stored in an associative array is not guaranteed. You'll have to sort your output explicitly.

As the other answers say, the order in which an object's properties are iterated is not defined in the spec, even though the major browsers all iterate them in the defined order.

Chrome will enumerate them in order too, if all of the object's properties contain primitive values. John Resig gives more detail on Chrome's behavior here (under "for loop order"): http://ejohn.org/blog/javascript-in-chrome/

As pointed out Chrome's behaviour is perfectly valid.

This is a good case of where some OO thinking can help. Do you really want an associative array or just a list of objects?

var salesWeeks = [
    ["200911", "11 / 2009", "Fiscal 2009"],
    ...
]
...
for(var key in salesWeeks)
{
    arr.push(
        "<option value=\"" + salesWeeks[key][0] + "\">" +
        salesWeeks[key][1] + " (" + salesWeeks[key][2] + ")" +
        "<\/option>"
    );
}

would serve you better I think (to those that advocated some form of sort, the order is already defined - why do you want to do extra work?)

@curtainDog: NO! NO! Using “for .. in” with Array objects in JavaScript is bad - the entire point of most of the the responses here is that “for .. in” does not guarantee any order. Moreover, “for .. in” will grab properties from an object’s constructor’s prototype and will not iterate over nonexistent keys.

@Samnan: The spec simply says that iteration order is not guaranteed; this means that browsers are free to iterate in sorted order, in order of insertion, in random order, or however else they may. It’s just like a hash table - think of it as random, even if it happens to come out in some apparent order.

I’m fairly sure most browsers look for “for..in” with Array objects and iterate in numeric order so that things don’t break; however, it’s not really doing what most people who use it that way think it’s doing, and it should be avoided unless you specifically need object-type iteration.

It's not a real good practice but...

If you add a space to the value chrome will not consider value a number and won't sort them by value.

Example:

<select>
  <option value=" 3">Third</option>
  <option value=" 1">First</option>
  <option value=" 2">Second</option>
</select>

The good side is that you have not to add and then remove alphabetic characters from ID like someone suggested (don't remember if in this or other post with similar question), you could easily trim it but most of the times the space is just ignored and if you post or get those to another file they will simply see the integer value not the space.

Contrary to all the other answers, it is CERTAINLY A BUG IN CHROME

The reason:

If the data structure is a paper sack like Barry said then:

The values should always be randimized. This is not the case in chrome

If the data structure is sequential then:

The values should be in the sequence in which they are added to the structure

While other browsers follow the second approach, chrome follows neither and there is still no explanation of what is the sorting order chrome makes up for the data structure while it is accessed.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!