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…...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
