วัตถุ Javascript Vs JSON


208

ฉันต้องการเข้าใจความแตกต่างพื้นฐานอย่างชัดเจนระหว่างวัตถุ Javascript และสตริง JSON

สมมติว่าฉันสร้างตัวแปร JS ต่อไปนี้:

var testObject = {one: 1,"two":2,"three":3};

ไตรมาสที่ 1 ชื่อคีย์ / คุณสมบัติถูกต้องทั้งที่มี / ไม่มีเครื่องหมายคำพูด? (เช่น"one" : 1 )

ถ้าใช่ความแตกต่างคืออะไร?

Q2: ถ้าฉันแปลงวัตถุข้างต้นโดยใช้JSON.stringify(testObject)ความแตกต่างระหว่างวัตถุ JS เดิมและ JSON คืออะไร?

ฉันรู้สึกว่าพวกเขาเกือบจะเหมือนกัน โปรดอธิบายรายละเอียดเกี่ยวกับสิ่งนี้

Q3: สำหรับการวิเคราะห์สตริง JSON แนะนำวิธีการด้านล่างหรือไม่

var javascriptObj = JSON.parse(jSonString);

คำตอบ:


239
  1. ชื่อคีย์ / คุณสมบัติถูกต้องทั้งที่มี / ไม่มีเครื่องหมายคำพูด?

    ครั้งเดียวที่คุณต้องใส่กุญแจสำคัญในเครื่องหมายคำพูดเมื่อใช้วัตถุโน้ตตัวอักษรเป็นที่ที่สำคัญประกอบด้วยอักขระพิเศษ ( if, :, -ฯลฯ ) เป็นที่น่าสังเกตว่าคีย์ใน JSON ต้องอยู่ในเครื่องหมายคำพูดคู่

  2. ถ้าฉันแปลงวัตถุข้างต้นเป็น JSON โดยใช้var jSonString = JSON.stringify(testObject);แล้วความแตกต่างระหว่าง 2 (JS obj และ JSON) คืออะไร?

    JSONเป็นรูปแบบการแลกเปลี่ยนข้อมูล เป็นมาตรฐานที่อธิบายถึงวิธีการสั่งซื้อรายการและแผนที่ที่ไม่ได้เรียงลำดับสตริงบูลีนและตัวเลขสามารถแสดงเป็นสตริงได้ เช่นเดียวกับ XML และ YAML เป็นวิธีการส่งผ่านข้อมูลที่มีโครงสร้างระหว่างภาษา JSON เหมือนกัน วัตถุ JavaScript ในทางกลับกันเป็นประเภททางกายภาพ เช่นเดียวกับอาร์เรย์ PHP คลาส C ++ คลาส / struct วัตถุ JavaScript เป็นชนิดภายใน JavaScript

    นี่คือเรื่องราวของ สมมติว่าคุณซื้อเฟอร์นิเจอร์จากร้านค้าและคุณต้องการให้จัดส่ง อย่างไรก็ตามมีเพียงหนึ่งในสต็อคเท่านั้นที่เป็นรุ่นแสดง แต่คุณตกลงที่จะซื้อ

    ในร้านตู้ลิ้นชักที่คุณซื้อเป็นของมีชีวิต:

    var chestOfDrawers = {
        color: "red",
        numberOfDrawers: 4
    }

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

    {"color":"red","numberOfDrawers":4}

    เมื่อคุณได้รับจากนั้นคุณจะสร้างตู้ลิ้นชัก (อ่านแล้วแยกวิเคราะห์) ตอนนี้มันกลับมาในรูปแบบวัตถุ

    เหตุผลที่อยู่เบื้องหลัง JSON / XML และ YAML คือเพื่อให้สามารถถ่ายโอนข้อมูลระหว่างภาษาการเขียนโปรแกรมในรูปแบบทั้งสองภาษาที่เข้าร่วมสามารถเข้าใจได้ คุณไม่สามารถให้ PHP หรือ C ++ วัตถุ JavaScript ของคุณโดยตรง เพราะแต่ละภาษาแสดงถึงวัตถุที่แตกต่างกันภายใต้ประทุน อย่างไรก็ตามเนื่องจากเราได้ทำให้วัตถุเป็นสัญลักษณ์ของ JSON เช่นวิธีที่เป็นมาตรฐานในการแสดงข้อมูลเราสามารถส่งการแทนค่า JSON ของวัตถุไปยังไฟล์อีกภาษาหนึ่ง (C ++, PHP) พวกมันสามารถสร้างวัตถุ JavaScript ที่เรามีให้เป็นวัตถุของตัวเองตามการนำเสนอ JSON ของวัตถุ

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

    JSON.stringify({
        foo: new Date(),
        blah: function () { 
            alert('hello');
        }
    }); // returns the string "{"foo":"2011-11-28T10:21:33.939Z"}"
  3. สำหรับการแยกสตริง JSON เป็นวิธีที่แนะนำด้านล่าง? var javascriptObj = JSON.parse(jSonString);

    ใช่ แต่เบราว์เซอร์รุ่นเก่าไม่สนับสนุน JSON กำเนิด (IE <8) json2.jsเพื่อสนับสนุนเหล่านี้คุณควรจะรวมถึง

    หากคุณใช้ jQuery คุณสามารถโทรหาjQuery.parseJSON()ซึ่งจะใช้JSON.parse()ภายใต้ประทุนหากมีการรองรับและจะใช้การกำหนดเองเพื่อแยกอินพุต


4
@estndtv คุณกำลังพลาดจุด - แม้ว่าบนกระดาษ (หรือบนหน้าจอ) สตริง JSON และการแสดงของวัตถุ JS อาจมีลักษณะเหมือนกัน แต่ก็ไม่เหมือนกัน JSON เป็นเพียงวิธีที่จะแพ็ควัตถุลงในสตริงดังนั้นมันสามารถถ่ายโอนไปที่ไหนสักแห่งและต่อมาแตกกลับเข้าไปในวัตถุ
Alnitak

1
@Matt แบบอะนาล็อกที่ไม่ดี IMHO - JSON ไม่ควรใช้เพื่อทำให้เป็นอันดับวัตถุที่มีวิธีการ - เฉพาะวัตถุข้อมูลบริสุทธิ์
Alnitak

1
ดังนั้นถ้าวัตถุ JS มีวิธีการจะแปลงเป็นสตริง JSON ไม่สนใจมันอย่างสมบูรณ์ ... เหมือนในกรณีข้างต้น getIn และ getOut จะถูกละเว้นอย่างสมบูรณ์ .... มันทำงานอย่างไร?
testndtv

3
@Growler: โดยปกติแล้วฉันจะใช้ JSON หากจำเป็นต้องสร้าง "สิ่งของ" บนเซิร์ฟเวอร์และใช้ไฟล์ js หาก "สิ่งของ" แสดงผลตามที่เป็นอยู่ เครื่องมือสร้างความแตกต่างขนาดใหญ่อื่น ๆ คือคุณต้องใส่ฟังก์ชั่นและ / หรือวันที่เนื่องจาก JSON ไม่สามารถเป็นตัวแทนได้ดังนั้นคุณต้องหันไปใช้บริการไฟล์ JS หากคุณยังไม่แน่ใจโปรดถามเป็นคำถามแยกต่างหากใน Stack Overflow (แสดงตัวอย่างของเนื้อหาที่คุณต้องระบุเพื่อแสดงถึงไดอะล็อกของคุณ) และแย่งฉันด้วยลิงก์ ฉันยินดีที่จะตรวจสอบอย่างใกล้ชิด!
Matt

4
@ Matt คุณชายเป็นคนที่ฉลาดหลักแหลม! คำอธิบายของคุณนั้นชัดเจนชัดเจนและเข้าใจง่าย ฉันขอให้คุณเป็นจาวาสคริปต์ / ที่ปรึกษาการเขียนโปรแกรมของฉัน
FrankDraws

30

Q1: เมื่อกำหนดตัวอักษรของวัตถุในจาวาสคริปต์คีย์อาจมีเครื่องหมายคำพูดหรือไม่ ไม่มีความแตกต่างนอกจากคำพูดที่ช่วยให้คุณสามารถระบุคีย์บางอย่างที่จะทำให้ล่ามล้มเหลวในการแยกวิเคราะห์ถ้าคุณลองพวกเขาเปลือย ตัวอย่างเช่นหากคุณต้องการคีย์ที่เป็นเพียงเครื่องหมายอัศเจรีย์คุณจะต้องมีเครื่องหมายอัญประกาศ:

a = { "!": 1234 } // Valid
a = { !: 1234 } //  Syntax error

ในกรณีส่วนใหญ่คุณสามารถละเว้นอัญประกาศรอบคีย์บนตัวอักษรวัตถุ

Q2: JSON เป็นตัวแทนสตริงอย่างแท้จริง มันเป็นเพียงแค่สตริง ดังนั้นให้พิจารณาสิ่งนี้:

var testObject = { hello: "world" }
var jSonString = JSON.stringify(testObject);

เนื่องจากtestObjectเป็นวัตถุจริงคุณสามารถเรียกคุณสมบัติได้และทำสิ่งอื่นใดที่คุณสามารถทำได้กับวัตถุ:

testObject.hello => "world"

ในทางตรงกันข้ามjsonStringเป็นเพียงสตริง:

jsonString.hello => undefined

หมายเหตุความแตกต่างอื่น ๆ : ใน JSON คีย์ทั้งหมดต้องถูกยกมา ซึ่งตรงข้ามกับตัวอักษรของวัตถุโดยที่ไม่สามารถใส่เครื่องหมายอัญประกาศได้ตามคำอธิบายของฉันในไตรมาสที่ 1

ไตรมาสที่ 3 คุณสามารถแยกสตริง JSON โดยใช้JSON.parseและนี่คือวิธีที่ดีที่สุดในการทำ (ถ้าเบราว์เซอร์หรือเฟรมเวิร์กมีให้) คุณสามารถใช้เพียงevalเพราะ JSON เป็นรหัสจาวาสคริปต์ที่ถูกต้อง แต่วิธีการเดิมนั้นถูกแนะนำด้วยเหตุผลหลายประการ (eval มีปัญหาที่น่ารังเกียจมากมายที่เกี่ยวข้อง)


9

ปัญหาที่แก้ไขโดย JSON

สมมติว่าคุณต้องการแลกเปลี่ยนวัตถุ JavaScript ปกติระหว่างคอมพิวเตอร์สองเครื่องและคุณตั้งกฎสองข้อ:

  • ข้อมูลที่ส่งจะต้องเป็นสตริงปกติ
  • คุณลักษณะเท่านั้นที่สามารถแลกเปลี่ยนวิธีการจะไม่ถูกส่ง

ตอนนี้คุณสร้างวัตถุสองชิ้นบนโฮสต์แรก:

var obj1 = { one: 1,"two":2,"three":3 }; // your example
var obj2 = { one: obj1.one, two: 2, three: obj1.one + obj1.two };

คุณจะแปลงวัตถุเหล่านั้นเป็นสายอักขระเพื่อส่งไปยังโฮสต์ที่สองได้อย่างไร

  • สำหรับออบเจกต์แรกคุณสามารถส่งสตริงนี้ที่ได้รับจากการกำหนดตัวอักษร'{ one: 1,"two":2,"three":3 }'แต่ที่จริงแล้วคุณไม่สามารถอ่านตัวอักษรในส่วนสคริปต์ของเอกสาร (อย่างน้อยก็ไม่ง่าย) ดังนั้นobj1และobj2จะต้องดำเนินการจริงด้วยวิธีเดียวกัน
  • คุณจำเป็นต้องระบุคุณสมบัติทั้งหมดและค่าของพวกเขาและสร้างสตริงที่คล้ายกับวัตถุตัวอักษร

JSON ถูกสร้างขึ้นเพื่อเป็นทางออกสำหรับความต้องการที่เพิ่งกล่าวถึง: มันเป็นชุดของกฎเพื่อสร้างสตริงที่เทียบเท่ากับวัตถุโดยการแสดงรายการคุณลักษณะและค่าทั้งหมด (เมธอดจะถูกละเว้น)

JSON ทำให้การใช้คำพูดสองครั้งเป็นปกติสำหรับชื่อและค่าของแอตทริบิวต์

จำไว้ว่า JSON เป็นชุดของกฎเท่านั้น (มาตรฐาน)

มีการสร้างวัตถุ JSON จำนวนเท่าใด

เพียงหนึ่งมันถูกสร้างขึ้นโดยเครื่องยนต์ JS

เอ็นจิ้น JavaScript สมัยใหม่ที่พบในเบราว์เซอร์มีอ็อบเจกต์พื้นเมืองชื่อ JSON วัตถุ JSON นี้สามารถ:

  • ถอดรหัสสตริงที่สร้างโดยใช้มาตรฐาน JSON โดยใช้ JSON.parse (สตริง) ผลลัพธ์เป็นอ็อบเจ็กต์ JS ปกติที่มีแอ็ตทริบิวต์และค่าที่พบในสตริง JSON

  • เข้ารหัสแอตทริบิวต์ / ค่าของวัตถุ JS ปกติโดยใช้ JSON.stringify () ผลลัพธ์เป็นสตริงที่สอดคล้องกับชุดของกฎ JSON

วัตถุ JSON (เดียว) คล้ายกับตัวแปลงสัญญาณฟังก์ชั่นคือการเข้ารหัสและถอดรหัส

โปรดทราบว่า:

  • JSON.parse () ไม่ได้สร้างวัตถุ JSON มันสร้างวัตถุ JS ปกติไม่มีความแตกต่างระหว่างวัตถุที่สร้างขึ้นโดยใช้วัตถุตามตัวอักษรและวัตถุที่สร้างขึ้นโดย JSON.parse () จากสตริงที่สอดคล้องกับ JSON

  • มีวัตถุ JSON เดียวเท่านั้นซึ่งใช้สำหรับการแปลงทั้งหมด

กลับไปที่คำถาม :

  • Q1: อนุญาตให้ใช้เครื่องหมายอัญประกาศเดี่ยวสำหรับวัตถุตัวอักษร โปรดทราบว่าเครื่องหมายคำพูดจะใช้เป็นทางเลือกสำหรับชื่อแอตทริบิวต์และจำเป็นสำหรับค่าสตริง ตัวอักษรของวัตถุไม่ได้อยู่ในเครื่องหมายคำพูด

  • Q2: วัตถุที่สร้างจากตัวอักษรและการใช้ JSON.parse () เหมือนกันอย่างเคร่งครัด วัตถุทั้งสองนี้มีค่าเท่ากันหลังการสร้าง:

    var obj1 = { one: 1, "two": 2, "three": 3 };
    var obj2 = JSON.parse('{ "one": "1", "two": "2", "three": "3" }');

  • Q3: ในเบราว์เซอร์ที่ทันสมัยJSON.parse()ใช้ในการสร้างวัตถุ JS จากสตริงที่สอดคล้องกับ JSON (jQuery ยังมีวิธีการเทียบเท่าที่สามารถใช้ได้กับเบราว์เซอร์ทั้งหมด)


7

Q1 - ใน JS คุณจะต้องใช้เครื่องหมายอัญประกาศหากคีย์เป็นคำที่สงวนไว้หรือจะเป็นโทเค็นผิดกฎหมาย ใน JSON คุณต้องใช้เครื่องหมายคำพูดคู่กับชื่อคีย์เสมอ

Q2 - jsonStringเป็นรุ่นที่ต่อเนื่องกันของวัตถุอินพุต ...

Q3 - ซึ่งอาจถูกตัดทอนให้เป็นวัตถุที่มีลักษณะเหมือนกันโดยใช้JSON.parse()


1

คำถามมีคำตอบที่ดีอยู่แล้วฉันเพิ่มตัวอย่างเล็ก ๆ ด้านล่างซึ่งจะทำให้ง่ายต่อการเข้าใจคำอธิบายที่ให้ไว้ในคำตอบก่อนหน้า คัดลอกวางตัวอย่างด้านล่างลงใน IDE ของคุณเพื่อทำความเข้าใจและแสดงความคิดเห็นบรรทัดที่มีinvalid_javascript_object_no_quotesการประกาศวัตถุเพื่อหลีกเลี่ยงข้อผิดพลาดในการรวบรวมเวลา

// Valid JSON strings(Observe quotes)
valid_json = '{"key":"value"}'
valid_json_2 = '{"key 1":"value 1"}' // Observe the space(special character) in key - still valid


//Valid Javascript object
valid_javascript_object_no_quotes = {
    key: "value"  //No special character in key, hence it is valid without quotes for key
}


//Valid Javascript object
valid_javascript_object_quotes = {
    key:"value",  //No special character in key, hence it is valid without quotes for key
    "key 1": "value 1" // Space (special character) present in key, therefore key must be contained in double quotes  - Valid
}



console.log(typeof valid_json) // string
console.log(typeof valid_javascript_object_no_quotes) // object
console.log(typeof valid_javascript_object_quotes) // object

//Invalid Javascript object 
invalid_javascript_object_no_quotes = {
   key 1: "value"//Space (special character) present in key, since key is not enclosed with double quotes "Invalid Javascript Object"
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.