带你深入理解 JSON 数据格式,透彻 JavaScript 中 JSON.stringify() 和 JSON.parse() 方法

文章目录

    • **带你深入理解JSON,Javascriipt中的stringify()和parse()方法**
  • 简述JSON的历史
    • 语法
      • 1.简单值
      • 2.对象
      • 3.数组
        • 演示一个复杂的 JSON 数据:
    • 解析与序列化
      • JSON.stringify() 和 JSON.parse() 方法详解
        • 1.简单使用序列化对象
        • 2.stringify() 方法会省略一些属性(unfidefined)和函数以及原型成员
        • 3.stringify可以过滤结果
          • 当传入的参数是数组时
          • 当传入的是函数时
        • 4.字符串缩进
        • 5.JSON.parse() 方法
        • 6.使用 stringify() 和 parse() 时注意的点

带你深入理解JSON,Javascriipt中的stringify()和parse()方法

简述JSON的历史

2006年,Douglas Crockford 在国际互联网工程组制定了 JavaScript对象简谱(JSON,JavaScript Object Notation)标准,即 RFC 4627。但实际上,JSON早在2001年就开始使用了。JSON 是 JavaScript 的严格子集,利用JavaScript 中的几种模式来表示结构化数据。
理解JSON最关键了一点是要把它当成一种数据格式,而不是编程语言。JSON 不属于 JavaScript,它们只是有相同的语法而已。JSON 也不是只能在 JavaScript 中使用,它是一种通用数据格式。很多语言都有解析和序列化 JSON 的内置功能。

语法

JSON 语法支持表示三种类型的值。

  1. 简单值:字符串、数值、布尔值和 null 可以在JSON 中出现,就像在 JavaScript 中一样。特殊值 undefined 不可以。
  2. 对象:第一种复杂数据结构,对象表示有序键值对。每个值可以是简单值,也可以是复杂数据类型。
  3. 数组:第二种复杂数据类型,数组表示可以通过数值的索引访问的值的有序列表。数组的值可以是任意类型,包括简单值,对象,甚至其他数组。

1.简单值

最简单的 JSON 可以是一个数值。例如,下面是这个数值是有效的 JSON:
6
这个 JSON 表示数值 5。类似地,下面这个字符串也是有效的JSON:
"Hello world!"
注:JSON 字符串必须使用 双引号(单引号会导致语法错误)。布尔值和 null 本身也是有效的JSON 值。

2.对象

对象使用与 JavaScript 对象的字面量略为不同的方式表示。一下是JavaScript 中对象字面量:
let user = {
	name: "sa",
	age: 18,
	phone: "1983472343"
}

但在 JSON 中的对象必须使用双引号把属性名包围起来。如下代码与前面代码是相同的:

let object = { 
	"name": "sa",
	"age": 18,
	"phone": "1983472343"
};

而用 JSON 表示相同的对象的语法是:

{
	"name": "sa",
	"age": 18,
	"phone": "1983472343"
}

注:与 JavaScript 对象字面量相比,JSON 主要有两处不同。首先,没有变量声明(JSON 中没有变量)。其次,最后没有分号(不需要,因为不是 JavaScript 语法)。同样,用引号将属性名包围起来才是有效的 JSON。属性值可以是简单值或复杂数据类型值,后者可以在对象中在嵌入对象。

3.数组

JSON的第二种复杂数据类型是数组。数组在 JSON 中使用 JavaScript 的数组字面量形式来表示。

如下是一个 JavaScript 数组:

let values = ['sa',18,true];

在 JSON 中同样可以使用类似的语法表示相同的数组:

["sa",18,true]

注意:这里没有变量,也没有分号。数组可以和对象混合使用,用来表示更加复杂的数据结构。

演示一个复杂的 JSON 数据:

[
{
    "name":"sa",
    "age":18,
    "address":"上海",
    "detail":[
        {
            "birthday":"2000年11月20号",
            "interesting":"game"
        },
        {
            "height":180,
            "weight":160,
            "isAdult":true
        }
    ]
},
{
    "name":"sb",
    "age":16,
    "address":"上海",
    "detail":[
        {
            "birthday":"2000年11月20号",
            "interesting":"game"
        },
        {
            "height":170,
            "weight":120,
            "isAdult":false
        }
    ]
}
]

解析与序列化

JSON 的迅速流行并不仅仅因为其语法与 JavaScript 类似,很大程度上还因为 JSON 可以直接被解析成可用的Javascript 对象。JSON 对象有两个方法 :stringify() 和 parse()。简单情况下,这两个方法分别可以将 JavaScript 序列化为 JSON 字符串,以及将 JSON 解析成原生的 JavaScript 值。

JSON.stringify() 和 JSON.parse() 方法详解

这是一个将 JavaScript 数据序列化成 JSON 字符串的方法。默认情况下,JSON.stringify() 会输出一个不包含空格或缩进的 JSON 字符串。

1.简单使用序列化对象

   let person = {
        name: '张三',
        age: 20,
        family: {
            father: '李思',
            mather: '王琦'
        }
    }
console.log(JSON.stringify(person))
// 输出结果如下:
// {"name":"张三","age":20,"family":{"father":"李思","mather":"王琦"}}

2.stringify() 方法会省略一些属性(unfidefined)和函数以及原型成员

let person = {
        name: '张三',
        age: 20,
        money: Infinity,
        eat (){
            console.log('对象方法!')
        },
        address: NaN,
        girlfriend: undefined
    }
    console.log(JSON.stringify(person))
    // 输出:{"name":"张三","age":20,"money":null,"address":null}

如上例子中:NaN 和 Infinity 属性值会自动转换为 null,而对象里面的方法和 undifined 属性也自动省略了

3.stringify可以过滤结果

JSON.stringify() 这个方法可以传入第二个参数,起到过滤对象属性的作用。这个参数可以是数组也可以是一个函数。当我们传入一个函数时,我们可以接受两个参数,一个属性名(key)和属性值(value)。我们可以对传入的 key 对应的属性值,然后执行我们想要的操作。

当传入的参数是数组时

js中 person 代码中的属性

    let person = {
        name: '张三',
        age: 20,
        money: '200w',
        friend: {
          name: 'gg',
          age: 28,
          birthday: '2000.1.2'
        }
    }

执行如下语句,将 person 中的 name、age、friend过滤出来

   console.log(JSON.stringify(person,['name','age','friend']))

输出结果如下:
{“name”:“张三”,“age”:20,“friend”:{“name”:“gg”,“age”:28}}

当传入的是函数时

js 对象同上是 person

  console.log(JSON.stringify(person,(key,value) => {
        switch (key) { // 遍历属性名和属性值,return 出去的就是经过处理后的值,当然这里只是简单演示
            case 'money':
                return '3000w';
            case 'name': 
                return 'sa';
            case 'birthday':
                return '2000年1月2号';
            default:
                return value;
        }
    }))

打印结果:
{“name”:“sa”,“age”:20,“money”:“3000w”,“friend”:{“name”:“sa”,“age”:28,“birthday”:“2000年1月2号”}}

如上打印结果可知,当对象里面包含对象时,同名的属性值会一同修改,而最终转换成 JSON 字符串的属性值就是我们return 出去的值。

4.字符串缩进

JSON.stringify() 方法中,我们还可以传入第三个参数用于控制缩进和空格。在这个参数是数值(当参数大于10时会自动设置为10)时,表示每一级缩进空格数。也可以传入字符。

js中 person 对象

   let person = {
        name: '张三',
        age: 20,
        money: '200w',
        friend: {
          name: 'gg',
          age: 28,
          birthday: '2000.1.2'
        }
    }
 console.log(JSON.stringify(person,null,4))// 每一级缩进4个空格

打印结果如下(我并没有对打印结果进行JSON格式化):

{
    "name": "张三",
    "age": 20,
    "money": "200w",
    "friend": {
        "name": "gg",
        "age": 28,
        "birthday": "2000.1.2"
    }
}

5.JSON.parse() 方法

JSON.parse() 是解析 JSON 数据的一种方法,将 JSON 串解析成 JavaScript 中对象结构的 API。

当然该方法也可以额外接收一个函数,使用方法和JSON.stringify() 相同。同样接收属性名(key)和属性值(value)。这个函数也称为还原函数
如下演示一个案例。

    let jsonStr = '{"name":"张三","age":20,"money":"200w","newDate":"2022年"}'
    let userOne = null;
    userOne = JSON.parse(jsonStr,(key,value) => {
        if (key === 'newDate'){
            return Date.now() // 如果key是newDate则返回一个当前时间戳
        }else {
            return value
        }
    })
    console.log(userOne)

打印结果如下:
{name: ‘张三’, age: 20, money: ‘200w’, newDate: 1672752998876}

6.使用 stringify() 和 parse() 时注意的点

  1. 在stringify() 中要注意里面仅支持的数据类型,undifined 类型和对象方法等是不支持序列化的。
  2. 我们可以使用 stringify() 和 parse() 之间的转换关系实现对象的深拷贝属性过滤,拷贝出来的对象和原对象是无关的,但是在自我引用的对象中使用 stringify() 会报错。

你可能感兴趣的:(javascript,json,前端)