JSON在JavaScript
一、JSON语法支持三种类型:
-
简单值:字符串、数值、null可以在JSON中出现,undefined不可以
(json中没有undefined是使用json方法深拷贝的缺陷)
let obj = { "name": "snake", t_underfined: undefined, t_null: null } let j1 = JSON.stringify(obj)//{"name":"snake","t_null":null} -
对象
JSON中的对象必须使用双引号把属性名包围起来
{ "name": "snake", "t_null": null } -
数组
二、解析与序列化
JSON.stringify(),JSON.parse()
1序列化
JSON.stringify(),除了接受要序列化的对象之外,还可以接收另外两个参数,一个用于过滤结果,一个用于字符串缩进:
1.1过滤结果
-
第二个参数是数组,JSON.stringify()返回结果只会包含数组中列出的属性
let book = { title: "javaScript", authors: [ "rose", "jack" ], edition: 4 } let jsonText = JSON.stringify(book,['title','authors']) console.log(jsonText); //{"title":"javaScript","authors":["rose","jack"]} -
第二个参数是替代函数(replacer),函数提供(key,value),key始终是字符串,可以根据key来对属性执行相应的操作。 return undefined 则该值回消失
let jsonText = JSON.stringify(book, (key, value) => { switch(key) { case "authors": return value.join("+") case "edition": return undefined //由于JSON没有underfined,序列化后edition会消失 default: return value } }) // {"title":"javaScript","authors":"rose+jack"} console.log(jsonText);
1.2字符串缩进
这个参数是数值时,表示每一级缩进的空格数最大为10超过10会自动设置为10;
为字符串时则使用该字符串来缩进,同理该字符串长度超过10只会取坐标【0-9】的前10个。
除了缩进JSON.stringify()还自动插入了换行符。
let jsonText = JSON.stringify(book, null, 4)
console.log(jsonText);
{
"title": "javaScript",
"authors": [
"rose",
"jack"
],
"edition": 4
}
使用字符串"-- "感受更直观一些:
let jsonText = JSON.stringify(book, null, "-- ")
console.log(jsonText);
{
-- "title": "javaScript",
-- "authors": [
-- -- "rose",
-- -- "jack"
-- ],
-- "edition": 4
}
1.3 toJSON()方法
下面用ES6的语法添加的toJSON()方法。箭头函数不能用来定义toJSON()方法,主要原因是箭头函数的词法作用域是全局作用域。
let book2 = {
title: "javaScript",
authors: [
"rose",
"jack"
],
edition: 4,
toJSON(){
return this.title
}
}
let jsonText = JSON.stringify(book2)
console.log(jsonText);//"javaScript"
注意: Date对象中有toJSON()方法,会自动将JavaScript的Date对象转换为ISO 8601日期字符串。
可以自定义解析过程的还原函数(reviver)来返回Date对象
1.4序列化过程**
1.有toJSON(),则调用toJSON()方法值,否则用默认的序列化
2.有提供第二个参数(看1.1),则应用过滤,传入过滤函数的值就是步骤1返回的值
3.第二步返回的值会进行相应的序列化,即:重复过程1,2,3
2 解析选项
JSON.parse()方法可以接收一个额外的参数,这个参数是个函数被称为还原函数(reviver) 同样return undefined 则意味着该对应的值和value会丢失
下面代码是book2被序列化( SON.stringify() )然后再被解析( JSON.parse() )后的结果, date对象由于序列化的时候被自身的toJSON()变成了字符串,解析出来也是一个字符串
let book2 = {
title: "javaScript",
authors: [
"rose",
"jack"
],
edition: 4,
date: new Date()
}
let jsonText = JSON.stringify(book2)
let book3 = JSON.parse(jsonText)
console.log(book2);
// { title: 'javaScript',
// authors: [ 'rose', 'jack' ],
// edition: 4,
// date: 2021-04-12T08:38:59.420Z }
console.log(book3);
// { title: 'javaScript',
// authors: [ 'rose', 'jack' ],
// edition: 4,
// date: '2021-04-12T08:38:59.420Z' },这里date变成了字符串
可以添加第二个参数来还原date:
let book4 = JSON.parse(jsonText, (key, value) =>
key === "date" ? new Date(value) : value )//传进来是date则转换为Date(),其他的不变
console.log(book4);
// { title: 'javaScript',
// authors: [ 'rose', 'jack' ],
// edition: 4,
// date: 2021-04-12T08:43:31.641Z } 这里date是Date()对象了
参考
JavaScript高级程序设计 第23章 JSON