什么是JSON对象
严格意义上JSON是文本对象
全局作用域下JSON是Object对象
JSON格式——是一种轻量级的、基于文本的、与语言无关的语法,用于定义数据交换格式,来源于ECMAScript编程语言,独立于编程语言
JSON的特征
- JSON就是一串字符串,使用特定的符号标注;{}表示对象,[]表示数组,""内是属性键或者值
- JSON键:只能是字符串,必须用双引号包裹
- JSON值:object、array、number、string、true、false、null
- number只能是十进制,最后不能有逗号;属性不能是Symbol类型,函数、Date类型都不行、undefined也不行
JSON.parse
是个函数reviver(k,v),将JSON字符串序列化;k表示当前要转换的字符串,v表示当前要转换的属性值;如果该函数返回undefined,那么该属性将会被删除
const jsonStr = `{
"name":"John",
"age":18,
"IDcard":"xxxxxxxx"
}`
console.log(JSON.parse(jsonStr,(k,v)=>{
if(k === "IDcard"){
return undefined;
}else {
return v;
}
})); // {name: 'John', age: 18}
注意键的输出顺序;遇到嵌套的对象会后遍历,并且嵌套的对象是从里往外打印
const jsonStr = `{
"name":"John",
"age":18,
"children":{
"name1":"张三",
"age1":10,
"children1":{
"name2":"李四"
}
}
}`
console.log(JSON.parse(jsonStr,(k,v)=>{
console.log(k)
}));
// name age name1 age1 name2 children1 children
注意里面的this,用处很大,注意不能使用箭头函数
console.log(JSON.parse(jsonStr,function(k,v){
console.log(k,this)
}));
// 可以看到输出当前的对象,包含嵌套对象的键,不包含嵌套的值
// 最后还会输出一个空对象
JSON.stringify
将内容转换成JSON字符串;JSON.stringify(value[, replacer [, space]])
value——将要序列化成 一个 JSON 字符串的值。
replacer:可选参数,过滤属性或者处理值,可以是数组或者函数
- 如果参数是函数,在序列化过程中,每个值都会经过函数的处理,在开始时,replacer 函数会被传入一个空字符串作为 key 值,代表着要被 stringify 的这个对象;随后每个对象或数组上的属性会被依次传入
- 如果返回一个 Number, 转换成相应的字符串作为属性值被添加入 JSON 字符串。
- 如果返回一个 String, 该字符串作为属性值被添加入 JSON 字符串。
- 如果返回一个 Boolean, "true" 或者 "false" 作为属性值被添加入 JSON 字符串。
- 如果返回任何其他对象,该对象递归地序列化成 JSON 字符串,对每个属性调用 replacer 方法。除非该对象是一个函数,这种情况将不会被序列化成 JSON 字符串。
如果返回 undefined,该属性值不会在 JSON 字符串中输出
const obj = {
name:"Jhon",
age:45,
getName:()=>{},
birth:new Date()
}
JSON.stringify(obj,function(k,v) {
if(typeof v === "number"){
return undefined;
}
return v;
})
//{"name":"Jhon","birth":"2023-06-09T00:44:27.793Z"}
// 这里在测试的时候出现一个问题,第一个判断用!==将整个返回undefined,好像是对函数做了序列化
console.log(JSON.stringify(obj,function(k,v){
if(typeof v === "string"){
return 5;
}
return v
}
))
// {"name":5,"age":45,"birth":5}
console.log(typeof obj.name); // string
space:美化数组格式
- 如果参数是数字,代表留多少空格,上限是10,该值如果小于1则没有空格
console.log(JSON.stringify(obj,null,4))
- 如果参数是字符串,将用字符串作为空格,也是不能超过10个
console.log(JSON.stringify(obj,null,'\t')) // 结果和上面一样
console.log(JSON.stringify(obj,null,'abc'))
- 如果不提供参数或者为null,将没有空格
对undefined、函数、symbol的规则
如果作为属性值,那么该属性将被忽略
const obj = {
name:"Jhon",
age:45,
getName:()=>{},
birth:new Date(),
a:undefined,
b:Symbol('test')
}
console.log(JSON.stringify(obj))
// {"name":"Jhon","age":45,"birth":"2023-06-09T00:58:52.073Z"}
如果作为数组的值,那么返回null
console.log(JSON.stringify(["Jhon",()=>{},Symbol('test'),undefined,,]))
// ["Jhon",null,null,null,null]
单独序列化时返回undefined
console.log(JSON.stringify(()=>{})) // undefined
其他规则
- 对Date返回ISO字符串
- 对NaN、Infinite、null返回null
- 对bigInt报错,循环引用也会报错
- 对map、set只能序列化可枚举的值
- 如果对象上有一个属性是toJSON,那么只会序列化该方法返回的属性
const obj = {
name:"Jhon",
age:45,
getName:()=>{},
birth:new Date(),
a:undefined,
b:Symbol('test'),
toJSON:function(){
return {
name:"Jhon",
age:45
}
}
}
console.log(JSON.stringify(obj))
// {"name":"Jhon","age":45}