[TOC] #### 1. JSON 的由来 --- JSON 是一种非常重要的数据格式,它并不是编程语言,而是一种可以在服务器和客户端之间传输的数据格式 JSON 的全称是 JavaScript Object Notation,翻译后就是 JavaScript 对象符号 JSON 是由 Douglas Crockford 构想和设计的一种轻量级资料交换格式,算是 JavaScript 的一个子集 虽然 JSON 被提出来的时候是主要应用在 JavaScript 中,但是目前已经独立于编程语言,可以在各个编程语言中使用,很多编程语言都实现了将 JSON 转成对应模型的方式 目前 JSON 被使用的场景也越来越多: + 项目的某些配置文件 + 网络数据的传输 JSON 数据 + 非关系性数据库(nosql)将 json 作为存储格式 #### 2. JSON 基本语法 --- JSON 的顶层支持三种类型的值 简单值: 数字(Number)、字符串(String,必须使用双引号,不支持单引号)、布尔类型(Boolean)、null类型 对象值: 由 key、value 组成,key 必须是字符串类型,并且必须添加双引号 数组值: 数组元素可以是简单值、对象值、数组值 #### 3. JSON 的序列化 --- 为什么需要 JSON 序列化 ? ```javascript const obj = { name: 'how old are you ?' } // 将对象数据存储到 localStorage // setItem 的第二个参数需要是一个字符串 // 如果直接传入对象会自动转为字符串,变为 [object Object] localStorage.setItem('obj', obj) ``` 正确写法 ```javascript const obj = { name: 'how old are you ?' } // 将 obj 转为 json 格式的字符串 const objString = JSON.stringify(obj) localStorage.setItem('obj', objString) const jsonString = localStorage.getItem('obj') // 将 json 格式字符串转为对象 const info = JSON.parse(jsonString) console.log(info); ``` #### 4. stringify 序列化详解 --- JSON.stringify 序列化的第二个参数 ```javascript const obj = { name: 'liang', age: 18, height: 180 } // stringify 第二个参数 replacer // 传入数组:设定哪些需要转换 const objString = JSON.stringify(obj, ['name', 'age']) console.log(objString); // {"name":"liang","age":18} // 传入回调函数:可以对 value 进行修改 const objString2 = JSON.stringify(obj, (key, value) => { if (key === 'age') { return value + 2 } return value }) ``` JSON.stringify 序列化的第三个参数 ```javascript const obj = { name: 'liang', age: 18, height: 180 } // stringify 第三个参数 space // 传入字符串: 增强可读性,每一行前面添加指定字符 const objString = JSON.stringify(obj, null, '-') // { // -"name": "liang", // -"age": 18, // -"height": 180 // } // 传入数字: 增强可读性,每一行前面留有对应的空格,数字代表空格数量 const objString2 = JSON.stringify(obj, null, 2) // { // "name": "liang", // "age": 18, // "height": 180 // } ``` #### 5. parse 解析详解 --- 第二个参数传入回调函数,可以对 value 进行修改 ```javascript const obj = { name: 'liang', age: 18 } const objString = JSON.stringify(obj) const info = JSON.parse(objString, (key, value) => { if (key === 'age') { return value - 2 } return value }) console.log(info); // {name: 'liang', age: 16} ``` #### 6. 利用序列化深拷贝 --- 先序列化,再进行解析。此时两个新老对象就互不影响了 ```javascript const obj = { name: 'liang', info: { age: 18, height: 180 } } const newObj = JSON.parse(JSON.stringify(obj)) ``` 特别注意:如果对象中有函数值,那么函数不会被深拷贝,因为 json 不支持函数,stringify 会自动过滤掉函数值 ```javascript const obj = { name: 'liang', foo() { } } const jsonString = JSON.stringify(obj) console.log(jsonString); // {"name":"liang"} ```