JSON 详解
文章目录
- JSON 的由来
- JSON 的基本语法
- JSON 的序列化
- 简单使用
- stringify 方法之 replacer
- stringify 方法之 replacer 参数传入回调函数
- stringify 方法之 space
- stringify 方法之 toJSON
- parse 方法之 reviver
- 利用 stringify 和 parse 实现深拷贝
json 相信大家一定耳熟能详,但是其实 json 在 JavaScript 中很多细节,本文就来详细讲解 json 在 JavaScript 中那些隐藏的秘密
JSON 的由来
- JSON 是一种数据格式,而不是编程语言,目前广泛用于客户端和服务器之间传输的数据格式
- JSON 全称 JavaScript Object Notation(JavaScript 对象符号)
- JSON 是由Douglas Crockford构想和设计的一种轻量级资料交换格式,算是 JavaScript 的一个子集
- 虽然 JSON 被提出来的时候是主要应用 JavaScript 中,但是目前已经独立于编程语言,可以在各个编程语言中被广泛的使用
JSON 的基本语法
- JSON 支持三种类型的值:
- 简单值:数字、字符串(不支持单引号)、布尔类型、null 类型
- 对象值:由key、value组成,key是字符串类型,并且必须添加双引号,值可以是简单值、对象值、数组值
- 数组值:数组的值可以是简单值、对象值、数组值
tips:JSON 里面不能添加注释- 具体的写法大家应该都知道,这里就不写示例代码了
JSON 的序列化
相信这个大家都知道,在 JavaScript 中的 JSON 对象上存在两个方法 stringify 和 parse,就可以实现序列化
序列化是将数据结构或对象转换为符合 JSON 格式的字符串的过程
简单使用
const obj = {name: '张三',age: 18,frienfs: [{ name: '李四', age: 20 },{ name: '王五', age: 22 }],hobbies: ['篮球', '足球', '乒乓球']
}// 使用 stringify 方法转为 JSON 格式的字符串
const str = JSON.stringify(obj)// 使用 parse 方法将一个 JSON 格式的字符串转为一个对象
const newObj = JSON.parse(str)
stringify 方法之 replacer
-
stringify 方法的第一个参数大家都知道,那第二个参数(
replacer)了解吗? -
replacer 是一个可选参数,replacer 的作用是指定需要想转换的值,是一个数组,或 null(全部转换) ,如下:
const obj = {name: '张三',age: 18,friends: [{ name: '李四', age: 20 },{ name: '王五', age: 22 }],hobbies: ['篮球', '足球', '乒乓球'] }// 正常转换 const str1 = JSON.stringify(obj) console.log('str1: ', str1)// 排除 friends 和 hobbies const str2 = JSON.stringify(obj, ['name', 'age']) console.log('str2: ', str2) -
结果如图:

-
此时就可以发现,只转换了我们需要的部分,当我们存在这样的需求的时候,使用这个参数,是非常方便的
-
tips:所有以 symbol 为属性键的属性都会被完全忽略掉,即便replacer参数中强制指定包含了它们
stringify 方法之 replacer 参数传入回调函数
-
上述例子中可以一定程度上实现一些额外的需求,但是针对高度自定义的需求还是有点无能为力,那么此时我们可以给其参数改为传入一个回调函数
-
传入一个回调函数时,会接收两个参数,key 和 value,而每一次进行序列转换的时候就会执行一次,如下:
const obj = {name: '张三',age: 18,friends: [{ name: '李四', age: 20 },{ name: '王五', age: 22 }],hobbies: ['篮球', '足球', '乒乓球'] }const str = JSON.stringify(obj, (key, value) => {console.log(key, value)return value })console.log(str) -
执行结果如图:

-
比如我们需要给 name 的值添加一个 @ 符号,并年龄 +1,如下:
const obj = {name: '张三',age: 18,friends: [{ name: '李四', age: 20 },{ name: '王五', age: 22 }],hobbies: ['篮球', '足球', '乒乓球'] }const str = JSON.stringify(obj, (key, value) => {if (key === 'name') {return value + '@'}if (key === 'age') {return value + 1}return value })console.log(str) -
结果如图:

stringify 方法之 space
-
此方法除了第二个参数还存在第三个参数(
space),此参数的作用为指定缩进用的空白字符串,用于美化输出 -
当 space 是一个数字时:它代表有多少的空格;上限为 10; 该值若小于 1,则意味着没有空格,如下:
const obj = {name: '张三',age: 18,friends: [{ name: '李四', age: 20 },{ name: '王五', age: 22 }],hobbies: ['篮球', '足球', '乒乓球'] }// 正常转换 const str1 = JSON.stringify(obj) console.log('正常转换: ', str1)// 2个空格 const str2 = JSON.stringify(obj, null, 2) console.log('2个空格: ', str2) -
结果如图:

-
此时输出的结果,就不是单纯的一行字符串,而是经过美化的格式,在一些调试查看数据的时候,还是非常好用的
-
当 space 是一个字符串时:则每一级别会比上一级别多缩进该字符串(或该字符串的前 10 个字符),如下:
const obj = {name: '张三',age: 18,friends: [{ name: '李四', age: 20 },{ name: '王五', age: 22 }],hobbies: ['篮球', '足球', '乒乓球'] }// 正常转换 const str1 = JSON.stringify(obj) console.log('正常转换: ', str1)// 空格时 const str2 = JSON.stringify(obj, null, ' ') console.log('空格时: ', str2)// 使用制表符(\t)来缩进 const str3 = JSON.stringify(obj, null, '\t') console.log('制表符(\t): ', str3)// 字符长度超出 10 const str4 = JSON.stringify(obj, null, 'aaabbbcccdddeee') console.log('字符长度超出 10: ', str4) -
正常转换时,如图:

-
空格时,如图:

-
制表符时,如图:

-
字符长度超出 10 时,如图:

stringify 方法之 toJSON
如果一个被序列化的对象拥有
toJSON方法,那么该toJSON方法就会覆盖该对象默认的序列化行为:不是该对象被序列化,而是调用toJSON方法后的返回值会被序列化
-
这个方法还是很好理解的,就是原来是转换原对象,但是如果有这个方法的话就会以我们这个方法的返回值为基准,如下:
const obj = {name: '张三',age: 18,friends: [{ name: '李四', age: 20 },{ name: '王五', age: 22 }],hobbies: ['篮球', '足球', '乒乓球'],toJSON: function () {// 返回数字return 111} }console.log('toJSON: ', JSON.stringify(obj)) -
结果如图:

-
同样,可以更换为其他对象,如下:
const obj = {name: '张三',age: 18,friends: [{ name: '李四', age: 20 },{ name: '王五', age: 22 }],hobbies: ['篮球', '足球', '乒乓球'],toJSON: function () {// 返回数字return {name: '李白',descripton: '一个浪漫的人'}} }console.log('toJSON: ', JSON.stringify(obj, null, 2)) -
结果如图:

parse 方法之 reviver
-
reviver 也是一个函数,执行时机在在 parse 函数返回之前,所以也可也来进行拦截或者说修改解析前的原始值
-
使用如下:
const str = `{"name":"张三","age":18,"friends":[{"name":"李四","age":20},{"name":"王五","age":22}],"hobbies":["篮球","足球","乒乓球"]}`const obj = JSON.parse(str, (key, value) => {if (key === 'age') {return value + 2}return value }) console.log(obj) -
输出如图:

-
在生成的对象之后,我们也可以发现,年龄是发生了变化的
利用 stringify 和 parse 实现深拷贝
-
stringify 和 parse 搭配使用的时候,可以完成深拷贝,不敢存在一些限制,比如函数,循环引用,symbol 等等一些清空都是无法使用这种方式完成深拷贝的
-
只需要先使用 stringify 方法将对象转为 JSON 字符串,在使用 parse 方法进行解析即可,配合使用如下:
const obj = {name: '张三',age: 18,friends: [{ name: '李四', age: 20 },{ name: '王五', age: 22 }],hobbies: ['篮球', '足球', '乒乓球'] }const obj2 = JSON.parse(JSON.stringify(obj)) console.log('obj2: ', obj2)console.log('修改 obj2 的 name 属性的值为田七')obj2.name = '田七'console.log('obj: ', obj) console.log('obj2: ', obj2) -
结果如图:

-
可以看到,obj 并没有因为修改了 obj2 的值而受到影响,在一些简单的 JSON 形式的数据的对象时,使用此方法是一种非常不错的选择
相关文章:
JSON 详解
文章目录 JSON 的由来JSON 的基本语法JSON 的序列化简单使用stringify 方法之 replacerstringify 方法之 replacer 参数传入回调函数stringify 方法之 spacestringify 方法之 toJSONparse 方法之 reviver 利用 stringify 和 parse 实现深拷贝 json 相信大家一定耳熟能详&#x…...
我不想学JAVA---------JAVA和C的区别
前言 我一个研究方向是SLAM的为什么要来学JAVA。 从九月份开学到现在,已经学了Linux,数据结构,SLAM,C的基础操作,期间还参与编写了一本VHDL的教材。还有上课、考试什么的其他杂七杂八的事情就不说了。 读研好苦逼&…...
不能错过的AI前沿开源工具!
🌈🌈🌈🌈🌈🌈🌈🌈 欢迎关注公众号(通过文章导读关注:【11来了】),及时收到 AI 前沿项目工具及新技术 的推送 发送 资料 可领取 深入理…...
为什么深度学习神经网络可以学习任何东西
下图你所看到的,是著名的曼德尔布罗特集,我们可以见证这个集合呈现出的复杂形态: 要理解神经网络如何学习曼德尔布罗特集,我们首先需要从最基础的数学概念讲起:什么是函数?函数本质上是一个将输入转化为输出…...
使用 SpringSecurity 发送POST请求出现 403
问题场景 在使用 SpringSecurity 时对一些访问权限进行了设置, 在用户请求资源时出现了403错误 , 通过检查代码发现请求权限是开放的, 并且切换成 GET 请求也是可以通过, 换成POST 请求就无法通过。 解决方法 在 SpringSecurity 中关闭 CSRF 因为 前端向后台发送 post 请求…...
解决Typora笔记上传到CSDN上图片无法显示的问题
解决Typora笔记上传到CSDN上图片无法显示的问题 一、发现问题二、分析问题三、解决问题图床介绍所需工具PicGo软件安装操作下载安装PicGo配置PicGo 设置Typora 四、总结 一、发现问题 当我们使用Typora这款强大的Markdown编辑器记录笔记时,经常会遇到一个让人困扰的…...
Vue3.0+Echarts (可视化界面)
Vue3.0Echarts (可视化界面) 1. 简介2. 安装2.1 下载安装Node.js2.2 全局下载项目脚手架2.3 创建项目 1. 简介 2. 安装 2.1 下载安装Node.js 2.2 全局下载项目脚手架 以管理员身份执行 npm install -g vue/cli vue --version2.3 创建项目 vue crea…...
编程语言的未来:探索技术进步的轨迹
编程语言的未来:探索技术进步的轨迹 随着科技的飞速发展,编程语言在计算机领域中扮演着至关重要的角色。它们是软件开发的核心,为程序员提供了与机器沟通的桥梁。然而,未来的技术进步将如何影响编程语言的走向呢?让我…...
SOLIDWORKS使用技巧——SOLIDWORKS草图绘制时一定要完全定义
SOLIDWORKS草图的定义状态有多种,按是否报错区分,如下: 1. 正常状态:欠定义、完全定义; 2. 错误状态的:过定义、悬空、无解; 其中,错误状态需要修复,不然会影响模型重…...
网络类型之GRE和MGRE和NHRP
GRE-通用路由封装 是一种简单的三层VPN封装技术,属于虚拟的点到点网络类型 优点:支持IP 网络作为承载网络、支持多种协议、支持IP 组播,配置简单,容易布署。 缺点:缺少保护功能,不能执行如认证、加密、以…...
uniapp获取日期
1.使用new Date()方法获取系统今天的日期,显示格式为:2023-10-28 <template><view class"content">{{date}}</view> </template> <script>export default {data() {return {date: new Date().toISOString().sl…...
编码和解码的未来之路
hello,我是小索奇。在计算机科学的世界中,编码和解码是无处不在的神奇力量,而现代技术的巅峰之一就是 ChatGPT。让我们一起探讨编码和解码如何与 ChatGPT 这一人工智能的杰作相互结合,打开了无限可能的数字世界之门。 ChatGPT的魔…...
Prometheus实战篇:Prometheus监控redis
准备环境 docker-compose安装redis docker-compose.yaml version: 3 services:redis:image:redis:5container_name: rediscommand: redis-server --requirepass 123456 --maxmemory 512mbrestart: alwaysvolumes:- /data/redis/data: /dataport:- "6379:6379"dock…...
Vue2.Hello World
步骤: 准备容器引包(开发版本/生产版本)创建实例new Vue()添加配置项 el指定挂载点data提供数据 准备容器 就是新建一个div标签 引包 vue2版本中文文档:https://v2.cn.vuejs.org/v2/guide/ 尝试 Vue.js 最简单的方法是使用 …...
【单片机项目实战】温度控制系统
本项目的主要作用是实现温度调控,通过设定一个预定的温度值,实现实时检测外界温度,当外界温度小于预定值时,电机正转,实现降温效果;当外界温度大于预定值时,电机反转,实现升温效果&a…...
SpringMVC-视图
SpringMVC中的视图实现了View接口,作用是渲染数据,将Model中的数据展示给用户。render是渲染方法,可以看到渲染的视图是一个View类型的对象。 SpringMVC视图的种类有很多,默认有转发视图和重定向视图。 如果配置了Thymeleaf视图解…...
【React系列】Hook(一)基本使用
本文来自#React系列教程:https://mp.weixin.qq.com/mp/appmsgalbum?__bizMzg5MDAzNzkwNA&actiongetalbum&album_id1566025152667107329) 一. 认识hook 1.1. 为什么需要hook Hook 是 React 16.8 的新增特性,它可以让我们在不编写class的情况下…...
算法训练营Day28
#Java #贪心 开源学习资料 Feeling and experiences: 这周来到了贪心算法,简要概述: 贪心算法是一种在每个步骤中都采取最优解(即,在当前看来最好的解)的算法设计策略。它通常用于求解优化问题。这种方…...
鸿蒙OS应用开发之日期选择
前面学习了时间选择组件,实现了时间的选择,这样非常方便用户进行时间的输入,通过手动就可以输入时间,比直接文本输入要省不少时间,特别对于手机这样单手操作的设备,更加重要了。因此,日期的输入工作也不能落后,本文将要学习日期选择组件,这样就可以实现日期通过手上下…...
Mysql 查看表注释或字段注释
查看所有表的注释 SELECT table_name 表名, table_comment 表说明 FROM information_schema.TABLES WHERE table_schema ‘数据库名’ ORDER BY table_name 查询所有表及字段的注释 SELECT a.table_name 表名, a.table_comment 表说明, b.COLUMN_NAME 字段名, b.column_commen…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
全面解析数据库:从基础概念到前沿应用
在数字化时代,数据已成为企业和社会发展的核心资产,而数据库作为存储、管理和处理数据的关键工具,在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理,到社交网络的用户数据存储,再到金融行业的交易记录处理&a…...
