แทนค่า null ใน JSON


422

วิธีที่แนะนำสำหรับการคืนค่า null ใน JSON คืออะไร มีการตั้งค่าที่แตกต่างกันสำหรับดั้งเดิม?

ตัวอย่างเช่นหากวัตถุของฉันบนเซิร์ฟเวอร์มีจำนวนเต็มชื่อ "myCount" โดยไม่มีค่า JSON ที่ถูกต้องที่สุดสำหรับค่านั้นจะเป็น:

{}

หรือ

{
    "myCount": null
}

หรือ

{
    "myCount": 0
}

คำถามเดียวกันสำหรับ Strings - ถ้าฉันมีสตริง "myString" บนเซิร์ฟเวอร์เป็น JSON ที่ดีที่สุด:

{}

หรือ

{
    "myString": null
}

หรือ

{
    "myString": ""
}

หรือ (พระเจ้าช่วยฉันด้วย)

{
    "myString": "null"
}

ฉันชอบการประชุมสำหรับคอลเลกชันที่จะแสดงใน JSON เป็นคอลเลกชันที่ว่างเปล่าhttp://jtechies.blogspot.nl/2012/07/item-43-return-empty-arrays-or.html

อาร์เรย์ที่ว่างเปล่าจะถูกแทน:

{
    "myArray": []
}

สรุปแก้ไข

อาร์กิวเมนต์ 'การตั้งค่าส่วนตัว' ดูเหมือนเป็นจริง แต่มองในระยะสั้นเนื่องจากชุมชนเราจะต้องใช้บริการ / แหล่งข้อมูลที่แตกต่างกันมากขึ้นเรื่อย ๆ อนุสัญญาสำหรับโครงสร้าง JSON จะช่วยทำให้การบริโภคเป็นปกติและนำบริการดังกล่าวกลับมาใช้ใหม่ เท่าที่มีการกำหนดมาตรฐานฉันขอแนะนำให้ใช้การประชุมแจ็คสันส่วนใหญ่โดยมีข้อยกเว้นบางประการ:

  • วัตถุเป็นที่ต้องการมากกว่าดั้งเดิม
  • คอลเลกชันที่ว่างเปล่าเป็นที่ต้องการมากกว่าศูนย์
  • วัตถุที่ไม่มีค่าแสดงเป็นโมฆะ
  • การส่งคืนค่าดั้งเดิม

หากคุณส่งคืนออบเจ็กต์ JSON ที่มีค่า Null เป็นส่วนใหญ่คุณอาจมีตัวเลือกสำหรับการเปลี่ยนโครงสร้างเป็นหลาย ๆ บริการ

{

    "value1": null,

    "value2": null,

    "text1": null,

    "text2": "hello",

    "intValue": 0, //use primitive only if you are absolutely sure the answer is 0

    "myList": [],

    "myEmptyList": null, //NOT BEST PRACTICE - return [] instead

    "boolean1": null, //use primitive only if you are absolutely sure the answer is true/false

    "littleboolean": false

}

JSON ด้านบนสร้างขึ้นจากคลาส Java ต่อไปนี้

package jackson;

import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonApp {

    public static class Data {

        public Integer value1;

        public Integer value2;

        public String text1;

        public String text2 = "hello";

        public int intValue;

        public List<Object> myList = new ArrayList<Object>();

        public List<Object> myEmptyList;

        public Boolean boolean1;

        public boolean littleboolean;

    }

    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        System.out.println(mapper.writeValueAsString(new Data()));
    }
}

Maven พึ่งพา:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.3.0</version>
</dependency>

5
ไม่มีวิธีที่ดีที่สุด เลือกสิ่งที่ง่ายที่สุดที่จะใช้สำหรับลูกค้าในกรณีการใช้งานคอนกรีต ด้วยจิตวิญญาณของการส่งคืนคอลเลกชันที่ว่างเปล่าแทนที่จะnullพิจารณาว่าลูกค้าของคุณดีกว่าด้วยสตริงที่ว่างเปล่าหรือnull- สตริงที่มีคำว่า "โมฆะ" นั้นแยกไม่ออกจากค่าที่ถูกต้องอย่าทำเช่นนั้น
Philipp Reichart

3
0 หรือสตริงว่างอาจมีความหมายแตกต่างจาก null ซึ่งอาจมีความหมายแตกต่างจากแอตทริบิวต์ที่ไม่มีอยู่ ถ้าคุณต้องการแทนค่า null ใช้ null มันชัดเจนที่สุด
John Sheehan

ใน Objective-C มีNSNullคลาสที่กำหนดซึ่งมีอินสแตนซ์ซิงเกิล การอ้างอิงไปยังอินสแตนซ์ที่เทียบเท่ากับ nullJSON ฉันเดาว่าภาษาอื่นสามารถทำสิ่งเดียวกันได้ แน่นอนว่าเราจะต้องตรวจสอบคลาสของวัตถุที่ได้รับก่อนที่จะส่งไปยังคลาสที่สันนิษฐานว่าเป็น "ไร้ค่าที่รับรู้" เหมือนเดิม
Hot Licks

2
โปรดทราบว่าการมีรายการ "null" ไม่ใช่วิธีปฏิบัติที่ดีที่สุดใน Java เช่นกัน: หากคาดว่ารายการนั้นว่างเปล่าให้เริ่มต้นรายการนั้นในรายการว่าง หากจำเป็นต้องคงว่างไว้ (เช่นเนื่องจากจะถูกแทนที่ด้วยรายการใหม่แทนที่จะถูกปรับเปลี่ยนเพื่อเพิ่มค่า) ให้กำหนดค่าเริ่มต้นเป็นรายการว่าง (เช่นCollections.emptyList()) การทำเช่นนั้นหลีกเลี่ยงข้อบกพร่องอ้างอิงที่เป็นโมฆะซึ่งอาจเป็นความเจ็บปวดได้
Periata Breatta

@HotLicks - เป็นไปได้เพียงเพราะ Objective-C ถูกพิมพ์แบบไดนามิก ตัวอย่างเช่นใน Java คุณไม่สามารถมีNullคลาส(มีประโยชน์) ได้เนื่องจากคุณจะสามารถกำหนดค่าให้กับออบเจ็กต์ประเภทหรือประเภทของตัวเองObjectเท่านั้น
Periata Breatta

คำตอบ:


378

ลองประเมินการแยกวิเคราะห์ของแต่ละ:

http://jsfiddle.net/brandonscript/Y2dGv/

var json1 = '{}';
var json2 = '{"myCount": null}';
var json3 = '{"myCount": 0}';
var json4 = '{"myString": ""}';
var json5 = '{"myString": "null"}';
var json6 = '{"myArray": []}';

console.log(JSON.parse(json1)); // {}
console.log(JSON.parse(json2)); // {myCount: null}
console.log(JSON.parse(json3)); // {myCount: 0}
console.log(JSON.parse(json4)); // {myString: ""}
console.log(JSON.parse(json5)); // {myString: "null"}
console.log(JSON.parse(json6)); // {myArray: []}

The tl; drที่นี่:

ส่วนในjson2ตัวแปรเป็นวิธีที่JSON ข้อมูลจำเพาะแสดงnullควรจะแสดง แต่เช่นเคยขึ้นอยู่กับสิ่งที่คุณทำ - บางครั้งวิธีที่ "ถูกต้อง" ในการทำเช่นนั้นไม่ได้ผลกับสถานการณ์ของคุณเสมอไป ใช้วิจารณญาณของคุณและทำการตัดสินใจอย่างชาญฉลาด


JSON1 {}

ส่งคืนวัตถุที่ว่างเปล่า ไม่มีข้อมูลที่มีและเป็นเพียงจะบอกคุณว่ากุญแจสำคัญในสิ่งที่คุณกำลังมองหา (ไม่ว่าจะเป็นmyCountหรือสิ่งอื่น) undefinedเป็นประเภท


JSON2 {"myCount": null}

ในกรณีนี้จะถูกกำหนดจริงแม้ว่าค่าที่เป็นmyCount nullสิ่งนี้ไม่เหมือนกับทั้ง "ไม่ใช่undefinedและไม่ใช่null" และหากคุณกำลังทดสอบเงื่อนไขหนึ่งหรืออีกเงื่อนไขหนึ่งสิ่งนี้อาจสำเร็จในขณะที่ JSON1 จะล้มเหลว

วิธีนี้เป็นวิธีที่ชัดเจนที่จะเป็นตัวแทนnullต่อข้อมูลจำเพาะ JSON


JSON3 {"myCount": 0}

ในกรณีนี้ myCount เป็น 0 นั่นคือไม่เหมือนกันและมันก็ไม่เหมือนกันnull falseหากคำสั่งเงื่อนไขของคุณประเมินmyCount > 0แล้วนี่อาจจะคุ้มค่า ยิ่งกว่านั้นหากคุณกำลังเรียกใช้การคำนวณตามค่าที่นี่ 0 อาจมีประโยชน์ หากคุณกำลังพยายามทดสอบnullอย่างไรก็ตามนี่เป็นจริงไม่ได้เลย


JSON4 {"myString": ""}

ในกรณีนี้คุณจะได้รับสตริงว่าง อีกครั้งเช่นเดียวกับ JSON2 มันถูกกำหนดไว้ แต่ว่างเปล่า คุณสามารถทดสอบif (obj.myString == "")แต่คุณไม่สามารถทดสอบหรือnullundefined


JSON5 {"myString": "null"}

นี่อาจจะทำให้คุณเดือดร้อนเพราะคุณตั้งค่าสตริงเป็นโมฆะ ในกรณีนี้obj.myString == "null"แต่มันเป็นไม่ได้ == null


JSON6 {"myArray": []}

สิ่งนี้จะบอกคุณว่าอาเรย์ของคุณmyArrayมีอยู่ แต่ว่างเปล่า myArrayนี้จะเป็นประโยชน์ถ้าคุณกำลังพยายามที่จะดำเนินการนับหรือการประเมินผลใน ตัวอย่างเช่นสมมติว่าคุณต้องการประเมินจำนวนรูปภาพที่ผู้ใช้โพสต์ - คุณสามารถทำได้myArray.lengthและจะส่งคืน0: กำหนด แต่ไม่มีรูปโพสต์


1
ขอบคุณมากมีประโยชน์มาก เป็นเพียงโหนดเล็ก ๆ เมื่อเล่น Json (Scala) serializes ตัวเลือก [สตริง] = ไม่มีผลเป็นJSON1เช่น{}
นีล

207

nullไม่ใช่ศูนย์ ไม่ใช่ค่าต่อ se : เป็นค่าภายนอกโดเมนของตัวแปรที่ระบุว่าข้อมูลที่หายไปหรือไม่รู้จัก

มีเพียงวิธีเดียวในการเป็นตัวแทนnullใน JSON ตามข้อกำหนด ( RFC 4627และjson.org ):

2.1 ค่า

ค่า JSON ต้องเป็นวัตถุอาร์เรย์ตัวเลขหรือสตริงหรืออย่างใดอย่างหนึ่ง
สามชื่อจริงต่อไปนี้:

  false null จริง

ป้อนคำอธิบายรูปภาพที่นี่


8
มันเป็นความอัปยศที่ null จะต้องมีอยู่ทั้งหมด 4 ตัวอักษรเพื่ออะไร คงจะเป็นการดีที่จะยกเว้นค่าทั้งหมด json = '{"myValue":}';
Richard A Quadling

119
@Richard A Quadling - ฉันเป็นผู้ติดตามของ "Hal Abelson" ต้องมีการเขียนโปรแกรมเพื่อให้ผู้คนได้อ่าน ฉันต้องการคำว่า 'โมฆะ' เพื่อยืนยันความตั้งใจของโปรแกรมเมอร์ไม่ใช่แค่คำถามที่ละเลยโดยไม่ตั้งใจ
Scott Smith

13
@Dave May: "ค่า JSON ไม่ใช่โปรแกรม" - จุดของฉันเกี่ยวกับความตั้งใจในการส่งสัญญาณในทางที่ไม่คลุมเครือ ใช่มันมีค่าใช้จ่ายเพิ่มอีกสี่ตัวอักษรและสำหรับบางแอปพลิเคชัน ในหลายกรณีแม้ว่าประโยชน์ของการทำผิดดูผิดไปมากกว่าประโยชน์ของการปรับให้เหมาะสมเล็กน้อย
Scott Smith

11
@Dave ตาม json.org แล้ว JSON "เป็นเรื่องง่ายสำหรับมนุษย์ที่จะอ่านและเขียน"
Sophivorus

14
นอกจากนี้โปรดทราบว่าหากคุณมีปัญหากับอักขระ ASCII 4 ตัว JSON ไม่ใช่วิธีที่ดีที่สุดให้ดูที่Binary JSONหรือดีกว่าในรูปแบบไบนารีที่บริสุทธิ์
PhoneixS

26

มีทางเดียวเท่านั้นที่จะเป็นตัวแทนของnull; nullที่อยู่กับ

console.log(null === null);   // true
console.log(null === true);   // false
console.log(null === false);  // false
console.log(null === 'null'); // false
console.log(null === "null"); // false
console.log(null === "");     // false
console.log(null === []);     // false
console.log(null === 0);      // false

กล่าวคือ; หากไคลเอ็นต์ใด ๆ ที่ใช้การแทนค่า JSON ของคุณใช้===โอเปอเรเตอร์ มันอาจเป็นปัญหาสำหรับพวกเขา

ไม่มีค่า

หากคุณต้องการถ่ายทอดว่าคุณมีวัตถุที่myCountไม่มีค่าแอตทริบิวต์:

{ "myCount": null }

ไม่มีแอตทริบิวต์ / แอตทริบิวต์ที่ขาดหายไป

ถ้าคุณถ่ายทอดว่าคุณมีวัตถุที่ไม่มีคุณสมบัติ:

{}

รหัสลูกค้าจะพยายามเข้าถึงmyCountและรับundefined; มันไม่ได้มี

คอลเลกชันที่ว่างเปล่า

ถ้าคุณถ่ายทอดว่าคุณมีวัตถุที่มีคุณสมบัติmyCountที่เป็นรายการว่างเปล่า:

{ "myCount": [] }

+1 ตัวอย่างที่ดีพร้อมการเปรียบเทียบ แต่จะเป็นประโยชน์ในการแยกความแตกต่างระหว่าง javascript และ json ความหมายการเป็นตัวแทนของ null ใน javascript ไม่จำเป็นต้องตรงกับของ json (แม้ว่าจะเป็น)
Mladen B.

15

ฉันจะใช้nullเพื่อแสดงว่าไม่มีค่าสำหรับคีย์นั้น ตัวอย่างเช่นใช้nullเพื่อแสดงว่า "ไม่ทราบจำนวนอุปกรณ์ในครัวเรือนของคุณที่เชื่อมต่อกับอินเทอร์เน็ต"

ในทางกลับกันใช้{}ถ้าคีย์นั้นไม่สามารถใช้ได้ ตัวอย่างเช่นคุณไม่ควรแสดงจำนวนถึงnullคำถาม "จำนวนรถยนต์ที่มีการเชื่อมต่ออินเทอร์เน็ตที่ใช้งานอยู่" จะถูกถามถึงคนที่ไม่ได้เป็นเจ้าของรถยนต์

ฉันจะหลีกเลี่ยงการผิดนัดค่าใด ๆ ยกเว้นค่าเริ่มต้นที่เหมาะสม ในขณะที่คุณอาจตัดสินใจที่จะใช้nullแทนค่าไม่มีแน่นอนไม่เคยใช้"null"เพื่อทำเช่นนั้น


7

ฉันจะเลือก "เริ่มต้น" สำหรับชนิดข้อมูลของตัวแปร ( nullสำหรับสตริง / วัตถุ0สำหรับตัวเลข) แต่ตรวจสอบรหัสที่จะใช้วัตถุที่แน่นอน อย่าลืมว่าบางครั้งมีความแตกต่างระหว่างnull/ ค่าเริ่มต้นกับ "ไม่แสดง"

ตรวจสอบรูปแบบวัตถุว่างเปล่า - บางครั้งมันจะดีกว่าที่จะผ่านวัตถุพิเศษบางอย่างแทนnull(เช่น[]อาร์เรย์แทนnullสำหรับอาร์เรย์หรือ""สตริง)


2

นี่คือตัวเลือกส่วนบุคคลและสถานการณ์ nullสิ่งสำคัญที่ต้องจำไว้คือสตริงที่ว่างเปล่าและศูนย์จำนวนที่มีแนวคิดที่แตกต่างจาก

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


1

ตามข้อมูลจำเพาะของ JSONคอนเทนเนอร์ที่อยู่นอกสุดไม่จำเป็นต้องเป็นพจนานุกรม (หรือ 'วัตถุ') ตามที่ระบุไว้ในความคิดเห็นส่วนใหญ่ข้างต้น นอกจากนี้ยังสามารถเป็นรายการหรือค่าเปล่า (เช่นสตริง, ตัวเลข, บูลีนหรือ null) ถ้าคุณต้องการที่จะเป็นตัวแทนของค่าโมฆะใน JSON สตริง JSON ทั้งหมด (ไม่รวมคำพูดที่มีสตริง JSON) nullเป็นเพียง ไม่มีการจัดฟันไม่มีวงเล็บไม่มีคำพูด คุณสามารถระบุพจนานุกรมที่มีคีย์ที่มีค่า Null ( {"key1":null}) หรือรายการที่มีค่า Null ( [null]) แต่สิ่งเหล่านี้ไม่ใช่ค่า Null เอง - เป็นพจนานุกรมและรายการที่เหมาะสม พจนานุกรมว่างเปล่า ( {}) หรือรายการว่างเปล่า ( []) นั้นใช้ได้อย่างสมบูรณ์แบบ แต่ก็ไม่มีผลใด ๆ

ใน Python:

>>> print json.loads('{"key1":null}')
{u'key1': None}
>>> print json.loads('[null]')
[None]
>>> print json.loads('[]')
[]
>>> print json.loads('{}')
{}
>>> print json.loads('null')
None

โปรดทราบว่ามันเป็นไวยากรณ์แบบฟอร์มของ McKeeman ที่แถบด้านข้างขวาของหน้าข้อมูลจำเพาะ JSON ที่เชื่อมโยงซึ่งตรวจสอบความถูกต้องของการยืนยันว่าเปลือยnullถือเป็น JSON ที่ถูกต้อง เนื้อความหลักและภาพประกอบมีความคลุมเครือและหากมีสิ่งใดที่ดูเหมือนจะแนะนำวัตถุและอาร์เรย์เท่านั้นที่ใช้ได้ที่รูท
yoyoyoyosef
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.