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