JavaScript数组和对象是否有固定的顺序?

5
这个问题对于我目前涉及创建HTML表格的JSON对象项目至关重要。我正在考虑在将它们呈现为HTML之前创建可以对我的数组/对象进行排序的函数。我唯一的担忧是,在JavaScript中,顺序并不重要,如果我用与另一个数组不同的顺序创建一个新的Array,它们最终会变得相同。
我想不出一种快速测试的方法,所以我在这里问。

Mongo是MongoDB的JavaScript shell,目前使用对象集合顺序来定义排序。我想知道这是否正确,并在nodejs中进行了一些测试并查看了这里... 显然是这样的。请参见http://docs.mongodb.org/manual/reference/aggregation/中的“$sort”。 - Paul
5个回答

9

其他人已经回答了关于数组的问题,所以我想提供一些关于对象的信息。

在这方面,标准不存在,但它的实际定义是对象将按插入顺序枚举,但数字会按升序排列并首先枚举。我说通常是因为这种行为远未标准化(也没有像jQuery这样的框架对其进行标准化,据我所知)。

您可以使用此jsFiddle测试浏览器:

http://jsfiddle.net/7cCpu/4/

对象 {"foo":"bar", "bar":"foo", "baz":"baz", "3":3, "2":2, "1":1} 的枚举如下:

foo, bar, baz, 3, 2, 1 // insertion order

1, 2, 3, foo, bar, baz // Chrome enumeration
1, 2, 3, foo, bar, baz // Opera
1, 2, 3, foo, bar, baz // IE9
foo, bar, baz, 3, 2, 1 // Firefox (!!!)

我没有安装Safari,但我认为它与Chrome相同。无论如何,重点是你可以做出假设——它不是随机的——但如果你依赖于精确枚举,使用数组可能是一个更好的选择。
更糟糕的是,正如duri上面指出的那样,删除和替换键的值会进一步改变事物。看看当我删除bar并执行Object.bar = "foo"然后枚举时会发生什么:
1, 2, 3, foo, baz, bar // Chrome enumeration
1, 2, 3, foo, baz, bar // Opera
1, 2, 3, foo, bar, baz // IE9 (!!!)
foo, baz, 3, 2, 1, bar // Firefox (!!!)

5

数组是通过(数字)索引进行枚举的。

而对象不是 - 顺序未定义,事实上Javascript标准明确声明顺序是未定义。有关更多详细信息,请参见 JavaScript保证对象属性顺序吗?


2

当对象属性的顺序不同时,一个很好的例子是这段代码:

var o = { foo: 1, bar: 2, baz: 3 };
delete o.bar;
o.bar = 2;
for (var i in o)    {
    document.write(o[i]);
}

这段代码在Firefox中显示132,但在Internet Explorer中显示123


1

在使用“for ... in”循环迭代时,我绝不会依赖于对象属性以任何特定的、甚至是一致的顺序出现。这只是一种脆弱的程序组合方式,特别是当很容易明确地强加自己的顺序时。

无论如何,在迭代数组时,您都不应该使用“for ... in”循环,所以这点无关紧要;显然,如果使用数字索引正确迭代,您将按一致可重复的顺序遍历属性。

如果将数组序列化为JSON表示形式,则从位置0到数组长度必须有每个索引属性的“某些东西”。这意味着长度为1000000的稀疏数组在大小上存在问题,但可以工作。


0

数组的枚举是按照索引顺序排列的。如果你使用 (for in) 或 for 循环遍历一个数组,它将会被排序。

因此,如果你创建两个不同顺序的数组,它们就不相同。

对象的枚举是基于浏览器的任意顺序。

我相信有些是按字母顺序排列的,有些把数字放在开头,有些放在结尾。


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