【问题标题】:Is the order of elements in a JSON list preserved?JSON 列表中元素的顺序是否保留?
【发布时间】:2011-11-05 01:41:42
【问题描述】:

我注意到 JSON 对象中元素的顺序不是原始顺序。

JSON 列表的元素呢?他们的秩序是否得到维护?

【问题讨论】:

    标签: javascript arrays json list


    【解决方案1】:

    是的,JSON 数组中元素的顺序被保留。来自RFC 7159 -The JavaScript Object Notation (JSON) Data Interchange Format (强调我的):

    对象是零个或多个名称/值的无序集合 对,其中名称是字符串,值是字符串、数字、 布尔值、空值、对象或数组。

    数组是零个或多个值的有序序列。

    术语“对象”和“数组”来自于 JavaScript。

    一些实现也确实保留了 JSON 对象的顺序,但这不能保证。

    【讨论】:

    • 但是,我已经与一些遇到过数组未排序问题的开发人员交谈过。看看ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf 中这段措辞奇怪的段落,“JSON 语法没有为值的排序定义任何特定含义。但是,JSON 数组结构通常用于排序有一些语义的情况。 '
    • @Cato 这段话并不意味着数组可能是无序的。这意味着对数组进行排序的原因可能是未知的,因为您没有指定对其进行排序的原因。
    【解决方案2】:

    保持数组 ([]) 中元素的顺序。 “对象”({})中的元素(名称:值对)的顺序不是,而且它们通常是“混乱”的,如果不是由 JSON 格式化程序/解析器本身然后是特定于语言的对象(字典、NSDictionary、Hashtable 等)用作内部表示。

    【讨论】:

      【解决方案3】:

      实际上,如果键是 NaN 类型,浏览器不会更改顺序。

      以下脚本将输出“一”、“二”、“三”:

      var foo={"3":"Three", "1":"One", "2":"Two"};
      for(bar in foo) {
          alert(foo[bar]);
      }
      

      而以下脚本将输出“三”、“一”、“二”:

      var foo={"@3":"Three", "@1":"One", "@2":"Two"};
      for(bar in foo) {
          alert(foo[bar]);
      }
      

      【讨论】:

      • 但这依赖于 JSON 的未定义行为。您与之交换的任何东西都可能具有不同的行为。
      • 这个答案讨论了一个对象。该问题与json“列表”有关,只能推断为均值数组,该数组按json规范进行语义排序(请参阅Jeremy的回答)。
      【解决方案4】:

      一些 JavaScript 引擎按插入顺序保存键。 V8,例如,keeps all keys in insertion order except for keys that can be parsed as unsigned 32-bit integers

      这意味着如果您运行以下任一命令:

      var animals = {};
      animals['dog'] = true;
      animals['bear'] = true;
      animals['monkey'] = true;
      for (var animal in animals) {
        if (animals.hasOwnProperty(animal)) {
          $('<li>').text(animal).appendTo('#animals');
        }
      }
      
      var animals = JSON.parse('{ "dog": true, "bear": true, "monkey": true }');
      for (var animal in animals) {
        $('<li>').text(animal).appendTo('#animals');
      }
      

      在使用 V8 的 Chrome 上,您将始终按此顺序获得 dogbearmonkey。 Node.js 也使用 V8。即使您有数千个项目,这也是正确的。 YMMV 与其他 JavaScript 引擎。

      演示herehere

      【讨论】:

      • 但这依赖于 JSON 的未定义行为。您与之交换的任何东西都可能具有不同的行为。
      • 它可能适用于小物体。有一个对象实现将前三个键/值对存储在一个数组中,并在添加第四个条目时切换到哈希表是非常合理的。或者当您的最终用户比您测试过的项目多一件时。
      【解决方案5】:

      “JSON 列表中元素的顺序是否保持不变?”不是一个好问题。您需要问“在执行 [...] 时是否保持 JSON 列表中元素的顺序?” 正如 Felix King 所指出的,JSON 是一种文本数据格式。它不会无缘无故地变异。不要将 JSON 字符串与 (JavaScript) 对象混淆。

      您可能正在谈论像JSON.stringify(JSON.parse(...)) 这样的操作。现在的答案是:这取决于实施。 99%* 的 JSON 解析器不维护对象的顺序,并维护数组的顺序,但您不妨使用 JSON 来存储类似的东西

      {
          "son": "David",
          "daughter": "Julia",
          "son": "Tom",
          "daughter": "Clara"
      }
      

      并使用维护对象顺序的解析器。

      *可能更多:)

      【讨论】:

      • 错了,至少如果您谈论的是 JSON 解析器的使用。 V8 维护了这个顺序,我猜它单独占 JSON 解析器使用量的 1% 以上。 code.google.com/p/v8/issues/detail?id=164#c1
      • @BenAtkin 有趣的是,您的链接指向关于 V8 如何维持秩序的解释。
      • "事实上的标准是匹配插入顺序,V8 也这样做,但有一个例外"
      • 所有人都是男性,但有一个例外:女性是女性。
      • @user123444555621 :D 声明:“所有人都是男性,但有一个例外:女性是女性”涵盖了所有可能的情况,但有一个例外:人类不能可以明确归类为两者之一或两者皆无。
      猜你喜欢
      • 2011-04-12
      • 2010-11-29
      • 1970-01-01
      • 1970-01-01
      • 2019-11-28
      • 2010-11-23
      相关资源
      最近更新 更多