【问题标题】:Do javascript arrays and objects have a set order?javascript 数组和对象有固定的顺序吗?
【发布时间】:2011-09-13 01:59:20
【问题描述】:

这个问题对于我目前涉及从 JSON 对象创建 HTML 表的项目之一至关重要。我在想我可以创建在将数组/对象呈现为 HTML 之前对它们进行排序的函数。我唯一担心的是 JavaScript 中的顺序无关紧要,如果我要使用与另一个 Array 相同的数据(以不同的顺序)创建一个新的 Array,它们最终会相同。

我想不出一个快速的方法来测试这个,所以我在这里问。

【问题讨论】:

  • Mongo 是 MongoDB 的 javascript shell,目前使用对象集顺序来定义排序。我想知道这是否正确,最后在 nodejs 中进行了一些测试,然后看这里.... 显然是这样。参见docs.mongodb.org/manual/reference/aggregation中的“$sort”

标签: javascript jquery arrays object


【解决方案1】:

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

在这一点上,标准是不存在的,但 de facto 的定义是对象将按插入顺序枚举,但数字按升序排列并首先枚举除外。我通常说,但这种行为远未标准化(像 jQuery 这样的框架也没有标准化它,AFAIK)。

您可以使用这个 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 相同。在任何情况下,关键是您可以做出假设——这不是随机的——但如果你依赖于精确的枚举,使用数组可能是一个更好的主意。

Even nastier 是 duri 上面指出的,删除和替换键的值会进一步改变事情。观察当我 delete 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 (!!!)

【讨论】:

    【解决方案2】:

    数组由(数字)索引枚举。

    对象不是 - 顺序没有定义,实际上 Javascript 标准明确声明顺序是 undefined。更多详情见Does JavaScript Guarantee Object Property Order?

    【讨论】:

      【解决方案3】:

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

      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

      【讨论】:

        【解决方案4】:

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

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

        如果将数组序列化为 JSON 表示,则从位置 0 到数组长度的每个索引属性都必须有 something。这意味着长度为 1000000 的稀疏数组在大小方面存在问题,但可行。

        【讨论】:

          【解决方案5】:

          数组上的枚举按索引排序。如果您在数组上枚举 (for in) 或 for 循环,它将被排序。

          因此,如果您创建两个具有不同顺序的项目的数组,那么它们就不相同。

          对象的枚举是根据浏览器的感觉排序的。

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

          【讨论】:

            猜你喜欢
            • 2018-02-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-08-08
            • 2021-02-11
            • 1970-01-01
            相关资源
            最近更新 更多