JS知识回顾——JSON

146 阅读3分钟

什么是JSON对象

严格意义上JSON是文本对象

全局作用域下JSON是Object对象

image.png

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)
}));
// 可以看到输出当前的对象,包含嵌套对象的键,不包含嵌套的值
// 最后还会输出一个空对象

image.png

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))

image.png

  • 如果参数是字符串,将用字符串作为空格,也是不能超过10个
console.log(JSON.stringify(obj,null,'\t')) // 结果和上面一样
console.log(JSON.stringify(obj,null,'abc'))

image.png

  • 如果不提供参数或者为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}