摘要:布爾值和也是有效的形式。同一個對象中絕對不應該出現(xiàn)兩個同名屬性。序列化選項還可以接受兩個參數(shù),用于指定以不同方式序列化對象。當傳入了有效縮進參數(shù)值,結果字符串就會包含換行符。對第步返回的每個值進行相應的序列化。
前言
JSON(JavaScript Object Notation,JavaScript對象表示法)是JavaScript的一個嚴格的子集,利用了JavaScript中的一些模式來表示結構化數(shù)據(jù)。
JSON是一種數(shù)據(jù)格式,不是一種編程語言,雖然具有相同的語法格式,但JSON并不從屬于JavaScript,也并不只有JavaScript才使用JSON,很多編程語言都有針對JSON的解析器和序列化器。
JSON的語法可以表示三種類型的值:簡單值、對象和數(shù)組。
簡單值最簡單的JSON數(shù)據(jù)形式就是簡單值,如:
JSON表示數(shù)值7的方式:
7
JSON表示字符串的方式:
"Hello Miyang!"
JavaScript字符串與JSON字符串最大的區(qū)別在于,JSON字符串必須使用雙引號。
布爾值和null也是有效的JSON形式。
我們來對比一下JSON中的對象和JavaScript字面量:
JavaScript字面量:
var person = { name: "Miyang", age: 21 };
或
var person = { "name": "Miyang", "age": 21 };
在JSON中的對象要求必須給屬性加引號:
{ "name": "Miyang", "age": 21 }
相比兩者,JSON沒有聲明變量,其次,末尾也沒有分號,最重要的一點,對象的屬性必須加雙引號。
在實際使用中,我們經常會遇到這樣的JSON數(shù)據(jù):
{ "name": "Miyang", "age": 21, "location": { "name": "Ping guo yuan", "city": "Beijing" } }
雖然該JSON中存在兩個name屬性,但由于它們分別屬于不同的對象,因此沒有問題。同一個對象中絕對不應該出現(xiàn)兩個同名屬性。
數(shù)組在JSON中,可以采用與JavaScript相同的語法表示一個數(shù)組:
["Miyang", 21, true]
同樣的,JSON數(shù)組也沒有變量和分號,數(shù)組和對象結合起來,可以構成較為復雜的數(shù)據(jù)集合。
[ { "name": "Miyang", "age": 21, "hobby": ["HTML", "CSS", "Javascript"] }, { "name": "Miyang", "age": 21, "hobby": ["HTML", "CSS", "Javascript"] }, { "name": "Miyang", "age": 21, "hobby": ["HTML", "CSS", "Javascript"] } ]二、解析與序列化
JSON的流行,更重要的原因是可以把JSON數(shù)據(jù)結構解析為有用的JavaScript對象,相對于XML數(shù)據(jù)結構來說優(yōu)勢極為明顯。如我們可以通過以下方法來獲取某個屬性:
person[0].nameJSON對象
早期JSON解析器基本通過JavaScript的eval()函數(shù),但是存在風險,因為可能會執(zhí)行一些惡意代碼。從ECMAScript5開始,定義了全局對象JSON,可以更方便的對JSON進行解析與序列化。
JSON.stringify()該方法可以將JavaScript對象序列化為一個JSON字符串,默認情況下,輸出的字符串不包含任何空格字符或縮進,如:
var json = { "name": "Miyang", "age": 21 }; console.log(JSON.stringify(json)); // 輸出結果 {"name":"Miyang","age":21}
在序列化JavaScript對象時,所有函數(shù)即原型成員都會被有意忽略,不體現(xiàn)在結果中,值為undefined的任何屬性也會被跳過,如:
var json = { "name": "Miyang", "age": 21, "test": undefined }; console.log(JSON.stringify(json)); // 輸出結果 {"name":"Miyang","age":21}JSON.parse()
該方法可以將JSON字符串轉換為JSON對象,如:
var jsonTest = "{"name": "Miyang","age": 21,"test": "undefined"}"; console.log(JSON.parse(jsonTest)); // 輸出結果 { name: "Miyang", age: 21, test: "undefined" }
如果傳給JSON.parse()的字符串不是有效的JSON,該方法會拋出錯誤。
序列化選項JSON.stringfiy() 還可以接受兩個參數(shù),用于指定以不同方式序列化JavaScript對象。
第一個參數(shù)是過濾器,可以是一個數(shù)組,也可以是一個函數(shù)。
第二個參數(shù)是一個選項,表示是否在JSON字符串中保留縮進。
如果過濾器參數(shù)是數(shù)組,那么返回的結果就只包含數(shù)組中列出的屬性,如:
var json = { "name": "Miyang", "age": 21 }; console.log(JSON.stringify(json, ["name"])); // 輸出結果 {"name":"Miyang"}
如果過濾器參數(shù)是函數(shù),則該函數(shù)可以接收兩個參數(shù),屬性名和屬性值,隨后根據(jù)函數(shù)對結果進行過濾,如:
var json = { "name": "Miyang", "age": 21, "hobby": ["HTML", "CSS"] }; console.log(JSON.stringify(json, function(key, value) { switch(key) { case "name": return value + "!!!"; case "age": return 18; case "hobby": return undefined; default: return value; } })); // 輸出結果 {"name":"Miyang!!!","age":18}
這里注意,如果函數(shù)返回了undefined,那么相應的屬性會被忽略。
字符串縮進JSON.stringify()的第三個方法用于控制結果中的縮進和空白符,如果該參數(shù)是一個數(shù)值,則表示每個縮進的空格數(shù),最大縮進為10,大于10的值會自動轉換為10。當傳入了有效縮進參數(shù)值,結果字符串就會包含換行符。
var json = { "name": "Miyang", "age": 21, "hobby": ["HTML", "CSS"] }; console.log(JSON.stringify(json, null, 2)); // 輸出結果 { "name": "Miyang", "age": 21, "hobby": [ "HTML", "CSS" ] }
如果縮進參數(shù)是一個字符串,則這個字符串將在JSON字符串在作為縮進字符,同樣的,長度不能超過10個字符長,否則只顯示前10個字符。
var json = { "name": "Miyang", "age": 21, "hobby": ["HTML", "CSS"] }; console.log(JSON.stringify(json, null, "-")); // 輸出結果 { -"name": "Miyang", -"age": 21, -"hobby": [ --"HTML", --"CSS" -] }toJSON()方法
當JSON.stringify()不能滿足需求時,可以給對象定義toJSON()方法,返回其自身的JSON數(shù)據(jù)格式。
var json = { "name": "Miyang", "age": 21, "address": { "city": "Beijing" }, toJSON: function() { return this.name; } }; console.log(JSON.stringify(json)); // 輸出結果 "Miyang"
可以讓這個方法返回undefined,如果此時包含它的對象嵌入在另一個對象中,會導致它的值變成null,如果是頂級對象,則返回undefined。
var json = { "name": "Miyang", "age": 21, "address": { "city": "Beijing" }, toJSON: function() { return undefined; } }; console.log(JSON.stringify(json)); // 輸出結果 undefined
var json = { "name": "Miyang", "age": 21, "address": { "city": "Beijing", toJSON: function() { return undefined; } } }; console.log(JSON.stringify(json)); // 輸出結果 {"name":"Miyang","age":21}序列化內部工作順序
我們需要了解一下序列化內部工作順序,假設把一個對象傳入JSON.stringify(),序列化該對象的順序如下:
如果存在toJSON()方法而且能取得有效值,則調用該方法,否則返回對象本身。
如果提供了第二個參數(shù),應用這個函數(shù)過濾器,傳入的值是第1步返回的值。
對第2步返回的每個值進行相應的序列化。
如果提供了第三個參數(shù),執(zhí)行相應的格式化。
解析選項JSON.parse()也可以接收另一個參數(shù),該參數(shù)是一個函數(shù),對每個鍵值對進行調用,被稱之為還原函數(shù)。同樣的,它接收兩個參數(shù),一個鍵和一個值,且需要返回一個值。
如果返回undefined,則表示要從結果中刪除相應的鍵,如果返回其他值,則將該值插入到結果中,在將日期字符串轉換為Date對象時,經常用到還原函數(shù)。
var json = { "name": "Miyang", "age": 21, "address": { "city": "Beijing" }, "date": new Date(2011, 11, 1) }; var jsonText = JSON.stringify(json); var jsonCopy = JSON.parse(jsonText, function(key, value) { if(key === "date") { return new Date(value); }else { return value; } }); console.log(jsonCopy.date.getTime()); // 輸出結果 1322668800000結束語
JSON是一個輕量級的數(shù)據(jù)格式,可以簡化表示復雜數(shù)據(jù)結構的工作量,了解其結構、掌握JavaScript對其的操作方法,可以更便捷的進行前后臺交互或數(shù)據(jù)處理。
參考資料:JavaScript高級程序設計(第三版)第20章
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/94917.html
摘要:本系列文章適合快速掌握入門語法,想深入學習的小伙伴可以看看阮一峰老師的入門本篇文章是對之前文章的一個補充,可以使代碼更簡潔函數(shù)參數(shù)默認值在傳統(tǒng)語法中如果想設置函數(shù)默認值一般我們采用判斷的形式在新的語法中我們可以在參數(shù)聲明的同時賦予默認值參數(shù) 本系列文章適合快速掌握 ES6 入門語法,想深入學習 ES6 的小伙伴可以看看阮一峰老師的《ECMAScript 6 入門》 本篇文章是對之前文章...
摘要:前提好幾周沒更新博客了,對不斷支持我博客的童鞋們說聲抱歉了。熟悉我的人都知道我寫博客的時間比較早,而且堅持的時間也比較久,一直到現(xiàn)在也是一直保持著更新狀態(tài)。 showImg(https://segmentfault.com/img/remote/1460000014076586?w=1920&h=1080); 前提 好幾周沒更新博客了,對不斷支持我博客的童鞋們說聲:抱歉了!。自己這段時...
閱讀 3265·2021-10-13 09:39
閱讀 2020·2021-09-27 13:36
閱讀 3082·2021-09-22 16:02
閱讀 2606·2021-09-10 10:51
閱讀 1588·2019-08-29 17:15
閱讀 1539·2019-08-29 16:14
閱讀 3520·2019-08-26 11:55
閱讀 2560·2019-08-26 11:50