2011-08-27 72 views
157

我注意到JSON对象中元素的顺序不是原始顺序。是否保存了JSON列表中元素的顺序?

JSON列表的元素呢?他们的订单是否维持?

+3

你必须更具体。 JSON是一种数据交换格式,基本上是**文本**。角色不会随意改变他们的位置。您将以与发送相同的方式收到它。 –

+1

我会引导人们在json.org上使用官方的JSON语法。 JSON没有“列表”。它有“数组”和“对象”。 –

回答

248

是的,JSON数组中元素的顺序被保留。从RFC 7159 -The JavaScript Object Notation (JSON) Data Interchange Format (重点煤矿):

一个目的是无序收集零个或多个名称/值 对,其中名是一个字符串,一个值是一个字符串,数字 布尔值,null ,对象或数组。

数组是订购的零或更多值的序列。

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

44

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

3

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

您可能在谈论像JSON.stringify(JSON.parse(...))这样的操作。现在答案是:这取决于实施。 JSON解析器的99%*不维护对象的顺序,并做维护阵列的顺序,但你还不如用JSON存储像

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

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

*可能更:)

+1

错误,至少如果你在谈论JSON解析器的用法。 V8维护订单,我的猜测是,它本身占JSON解析器使用量的1%以上。 http://code.google.com/p/v8/issues/detail?id=164#c1 –

+2

@BenAtkin有趣的是,您的链接指向V8如何不**保持订单的解释。 – user123444555621

+2

“事实上的标准是匹配 插入顺序,V8也是这样,但有一个例外” –

5

一些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'); 
} 

你会一直得到猴子的顺序,在Chrome,这使用V8。 Node.js也使用V8。即使你有成千上万的物品,这也会成立。 YMMV与其他JavaScript引擎。

演示herehere

+4

但是这依赖于JSON部分的未定义行为。您交换的任何内容都可能不具有相同的行为。 –

7

实际上,如果键的类型是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]); 
} 
+11

但是这依赖于JSON部分的未定义行为。您交换的任何内容都可能不具有相同的行为。 –

+0

这个答案讨论一个对象。这个问题涉及json“list”,它只能被推断为意味着数组,这是按照json规范的语义排序的(参见Jeremy的回答)。 – Tom

相关问题