ลำดับขององค์ประกอบในรายการ JSON ถูกสงวนไว้หรือไม่?


254

ฉันสังเกตเห็นลำดับขององค์ประกอบในวัตถุ JSON ไม่ใช่ลำดับเดิม

สิ่งที่เกี่ยวกับองค์ประกอบของรายการ JSON? คำสั่งซื้อของพวกเขายังคงอยู่หรือไม่?

คำตอบ:


370

ใช่ลำดับขององค์ประกอบในอาร์เรย์ JSON จะถูกเก็บไว้ จากRFC 7159 - รูปแบบการแลกเปลี่ยนข้อมูลวัตถุ JavaScript (JSON) รูปแบบการแลกเปลี่ยนข้อมูล (เหมืองที่เน้น):

วัตถุคือชุดสะสมที่ไม่มีการเรียงลำดับของคู่ชื่อ / ค่าศูนย์หรือมากกว่าโดยที่ชื่อคือสตริงและค่าคือสตริง, หมายเลข, บูลีน, null, วัตถุหรืออาร์เรย์

อาร์เรย์เป็นลำดับที่สั่งเป็นศูนย์หรือมากกว่าค่า

คำว่า "object" และ "array" มาจากข้อกำหนดของ JavaScript

การใช้งานบางอย่างยังรักษาลำดับของวัตถุ JSON เช่นกัน แต่สิ่งนี้ไม่รับประกัน


อย่างไรก็ตามฉันได้พูดคุยกับนักพัฒนาบางคนที่พบปัญหาที่ไม่ได้สั่งอาร์เรย์ ดูข้อความที่มีคำศัพท์แปลก ๆ นี้ในecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf 'ไวยากรณ์ JSON ไม่ได้กำหนดความหมายเฉพาะใด ๆ กับการเรียงลำดับของค่า อย่างไรก็ตามโครงสร้างอาร์เรย์ JSON มักจะใช้ในสถานการณ์ที่มีความหมายบางอย่างในการสั่งซื้อ '
Cato

74

ลำดับขององค์ประกอบในอาร์เรย์ ( []) ได้รับการปรับปรุง ลำดับของอิลิเมนต์ (ชื่อ: คู่ค่า) ใน "object" ( {}) ไม่ใช่และมันเป็นเรื่องปกติสำหรับพวกเขาที่จะ "jumbled" หากไม่ได้โดยการจัดรูปแบบ JSON / parser ตัวเองแล้วโดยวัตถุเฉพาะภาษา (พจนานุกรม NSDictionary, Hashtable และอื่น ๆ ) ที่ใช้เป็นตัวแทนภายใน


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]);
}

16
แต่นั่นก็ขึ้นอยู่กับพฤติกรรมที่ไม่ได้กำหนดในส่วนของ JSON สิ่งใดก็ตามที่คุณแลกเปลี่ยนด้วยอาจไม่เหมือนกัน
Hot Licks

3
คำตอบนี้กล่าวถึงวัตถุ คำถามที่เกี่ยวข้องกับ "รายการ" json ซึ่งสามารถอนุมานได้ว่าหมายถึงอาร์เรย์ซึ่งถูกจัดเรียงตามความหมายโดย json สเปค (ดูคำตอบของ Jeremy)
Tom

5

เอ็นจิ้น JavaScript บางตัวเก็บคีย์ในลำดับการแทรก V8 เช่นเก็บกุญแจทั้งหมดเพื่อแทรกยกเว้นปุ่มที่สามารถแยกวิเคราะห์เป็นไม่ได้ลงนามจำนวนเต็ม 32 บิต

ซึ่งหมายความว่าหากคุณเรียกใช้อย่างใดอย่างหนึ่งต่อไปนี้:

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 อื่น ๆ

สาธิตที่นี่และที่นี่


7
แต่นั่นก็ขึ้นอยู่กับพฤติกรรมที่ไม่ได้กำหนดในส่วนของ JSON สิ่งใดก็ตามที่คุณแลกเปลี่ยนด้วยอาจไม่เหมือนกัน
Hot Licks

1

"ลำดับขององค์ประกอบในรายการ JSON ยังคงอยู่หรือไม่" ไม่ใช่คำถามที่ดี คุณต้องถามว่า "ลำดับขององค์ประกอบในรายการ JSON นั้นได้รับการดูแลรักษาเมื่อทำ [... ] หรือไม่" ดังที่เฟลิกซ์คิงชี้ให้เห็น JSON เป็นรูปแบบข้อมูลที่เป็นข้อความ ไม่เปลี่ยนแปลงโดยไม่มีเหตุผล อย่าสับสนระหว่างสตริง JSON กับวัตถุ (JavaScript)

JSON.stringify(JSON.parse(...))คุณอาจจะพูดคุยเกี่ยวกับการดำเนินงานเช่น ตอนนี้คำตอบคือ: ขึ้นอยู่กับการนำไปใช้ 99% * ของตัวแยกวิเคราะห์ JSON ไม่รักษาลำดับของวัตถุและรักษาลำดับของอาร์เรย์ แต่คุณอาจใช้ JSON เพื่อจัดเก็บสิ่งที่ชอบ

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

และใช้ parser ที่รักษาลำดับของวัตถุ

* อาจจะยิ่ง :)


1
ผิดอย่างน้อยถ้าคุณกำลังพูดถึงการใช้งานตัวแยกวิเคราะห์ JSON V8 รักษาคำสั่งซื้อและฉันเดาว่ามันเป็นเพียงบัญชีสำหรับการแยกวิเคราะห์ JSON มากกว่า 1% code.google.com/p/v8/issues/detail?id=164#c1
Benjamin Atkin

3
@BenAtkin เป็นเรื่องตลกที่ลิงค์ของคุณชี้ไปที่คำอธิบายว่า V8 ไม่รักษาลำดับได้อย่างไร
user123444555621

2
"มาตรฐานตามพฤตินัยคือการจับคู่คำสั่งการแทรกซึ่ง V8 ทำเช่นนั้น แต่มีข้อยกเว้นหนึ่งข้อ"
Benjamin Atkin

14
มนุษย์ทุกคนเป็นเพศชาย แต่มีข้อยกเว้นหนึ่งข้อ: ผู้หญิงเป็นเพศหญิง
user123444555621
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.