JSON 详解

文章目录

    • JSON 的由来
    • JSON 的基本语法
    • JSON 的序列化
      • 简单使用
      • stringify 方法之 replacer
      • stringify 方法之 replacer 参数传入回调函数
      • stringify 方法之 space
      • stringify 方法之 toJSON
      • parse 方法之 reviver
    • 利用 stringify 和 parse 实现深拷贝

json 相信大家一定耳熟能详,但是其实 json 在 JavaScript 中很多细节,本文就来详细讲解 json 在 JavaScript 中那些隐藏的秘密

JSON 的由来

  1. JSON 是一种数据格式,而不是编程语言,目前广泛用于客户端和服务器之间传输的数据格式
  2. JSON 全称 JavaScript Object Notation(JavaScript 对象符号)
    1. JSON 是由Douglas Crockford构想和设计的一种轻量级资料交换格式,算是 JavaScript 的一个子集
    2. 虽然 JSON 被提出来的时候是主要应用 JavaScript 中,但是目前已经独立于编程语言,可以在各个编程语言中被广泛的使用

JSON 的基本语法

  1. JSON 支持三种类型的值:
    1. 简单值:数字、字符串(不支持单引号)、布尔类型、null 类型
    2. 对象值:由key、value组成,key是字符串类型,并且必须添加双引号,值可以是简单值、对象值、数组值
    3. 数组值:数组的值可以是简单值、对象值、数组值
  2. tips:JSON 里面不能添加注释
  3. 具体的写法大家应该都知道,这里就不写示例代码了

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

  1. stringify 方法的第一个参数大家都知道,那第二个参数(replacer)了解吗?

  2. 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)
    
  3. 结果如图:

    在这里插入图片描述

  4. 此时就可以发现,只转换了我们需要的部分,当我们存在这样的需求的时候,使用这个参数,是非常方便的

  5. tips:所有以 symbol 为属性键的属性都会被完全忽略掉,即便 replacer 参数中强制指定包含了它们

stringify 方法之 replacer 参数传入回调函数

  1. 上述例子中可以一定程度上实现一些额外的需求,但是针对高度自定义的需求还是有点无能为力,那么此时我们可以给其参数改为传入一个回调函数

  2. 传入一个回调函数时,会接收两个参数,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)
    
  3. 执行结果如图:
    在这里插入图片描述

  4. 比如我们需要给 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)
    
  5. 结果如图:
    在这里插入图片描述

stringify 方法之 space

  1. 此方法除了第二个参数还存在第三个参数(space),此参数的作用为指定缩进用的空白字符串,用于美化输出

  2. 当 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)
    
  3. 结果如图:

    在这里插入图片描述

  4. 此时输出的结果,就不是单纯的一行字符串,而是经过美化的格式,在一些调试查看数据的时候,还是非常好用的

  5. 当 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)
    
  6. 正常转换时,如图:

    在这里插入图片描述

  7. 空格时,如图:

    在这里插入图片描述

  8. 制表符时,如图:

    在这里插入图片描述

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

    在这里插入图片描述

stringify 方法之 toJSON

如果一个被序列化的对象拥有 toJSON 方法,那么该 toJSON 方法就会覆盖该对象默认的序列化行为:不是该对象被序列化,而是调用 toJSON 方法后的返回值会被序列化

  1. 这个方法还是很好理解的,就是原来是转换原对象,但是如果有这个方法的话就会以我们这个方法的返回值为基准,如下:

    const obj = {name: '张三',age: 18,friends: [{ name: '李四', age: 20 },{ name: '王五', age: 22 }],hobbies: ['篮球', '足球', '乒乓球'],toJSON: function () {// 返回数字return 111}
    }console.log('toJSON: ', JSON.stringify(obj))
    
  2. 结果如图:

    在这里插入图片描述

  3. 同样,可以更换为其他对象,如下:

    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))
    
  4. 结果如图:

    在这里插入图片描述

parse 方法之 reviver

  1. reviver 也是一个函数,执行时机在在 parse 函数返回之前,所以也可也来进行拦截或者说修改解析前的原始值

  2. 使用如下:

    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)
    
  3. 输出如图:

    在这里插入图片描述

  4. 在生成的对象之后,我们也可以发现,年龄是发生了变化的

利用 stringify 和 parse 实现深拷贝

  1. stringify 和 parse 搭配使用的时候,可以完成深拷贝,不敢存在一些限制,比如函数,循环引用,symbol 等等一些清空都是无法使用这种方式完成深拷贝的

  2. 只需要先使用 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)
    
  3. 结果如图:

    在这里插入图片描述

  4. 可以看到,obj 并没有因为修改了 obj2 的值而受到影响,在一些简单的 JSON 形式的数据的对象时,使用此方法是一种非常不错的选择

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/586890.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React Hooks 面试题 | 08.精选React Hooks面试题

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…

原生微信小程序如何动态配置主题颜色及如何调用子组件的方法

一、最终效果 二、步骤 1、在初始化进入项目时,获取当前主题色 2、把主题色定义成全局变量(即在app.js中设置) 3、tabBar也需要定义全局变量,在首页时需要重新赋值 三、具体实现 1、app.js onLaunch () {//获取主题数据this.set…

MySQL数据库导入100万数据不同方式的性能差异

本文将介绍MySQL数据库导入100万数据的三种方式性能比较。 三种方式分别为: (1)逐条INSERT (2)批量INSERT提交 (3)通过mysql自带的load data命令 应用场景:假设需要向100万个号码…

gitLab页面打tag操作步骤

作者:moical 链接:gitLab页面打tag简单使用 - 掘金 (juejin.cn) 来源:稀土掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 ---------------------------------------------------------------------…

RK3568测试tdd

RK3568测试tdd 一、门禁取包二、烧录三、跑tdd用例四、查看结果参考资料 一、门禁取包 右键复制链接,粘贴下载;解压到文件夹; 二、烧录 双击\windows\RKDevTool.exe打开烧写工具,工具界面击烧写步骤如图所示: 推荐…

二叉树BFS

前置知识 二叉树节点的定义 二叉树是递归定义的 /*** Definition for a binary tree node.(LeetCode)*/public class TreeNode {int val;TreeNode left;TreeNode right;TreeNode() {}TreeNode(int val) { this.val val; }TreeNode(int val, TreeNode…

【java爬虫】获取个股详细数据并用echarts展示

前言 前面一篇文章介绍了获取个股数据的方法,本文将会对获取的接口进行一些优化,并且添加查询数据的接口,并且基于后端返回数据编写一个前端页面对数据进行展示。 具体的获取个股数据的接口可以看上一篇文章 【java爬虫】基于springbootjd…

Android : 使用GestureOverlayView进行手势识别—简单应用

示例图: GestureOverlayView介绍: GestureOverlayView 是 Android 开发中用于识别和显示手势的视图组件。它允许用户在屏幕上绘制手势,并且应用程序可以检测和响应这些手势。以下是关于 GestureOverlayView 的主要特点: 手势识别…

nodejs+vue+微信小程序+python+PHP特困救助供养信息管理系统-计算机毕业设计推荐

通过走访某特困救助供养机构实际情况,整理特困救助供养机构管理的业务流程,分析当前特困救助供养机构管理存在的各种问题,利用软件开发思想对特困救助供养机构特困救助供养机构管理进行系统设计分析。通过服务端程序框架进行设计,…

MFC - 给系统菜单(About Dialog)发消息

文章目录 MFC - 给系统菜单(About Dialog)发消息概述笔记resource.h菜单的建立菜单项的处理MSDN上关于系统菜单项值的说法END MFC - 给系统菜单(About Dialog)发消息 概述 做了一个对话框程序, 在系统菜单(在程序上面的标题栏右击)中有"关于"的菜单. 这个是程序框架…

【MySQL】事务Transaction

1. 事务的概念 事务是什么 在业务逻辑中使用sql,面对一些较复杂的场景,是需要多个sql语句组合起来实现的。如:银行的转账业务,若客户A要转账100元给客户B,就要两条sql:A余额减100,B余额加100&a…

ES6语法(五)封装模块化公共工具函数、引入npm包 ,并上传到npm中进行下载

1. 模块化 模块化是指将一个大的程序文件,拆分为许多小的文件(模块),然后将小的文件组合起来。 1.1. 优点 (1)防止命名冲突 (2)代码复用 (3)高维护性 &…

【CFP-专栏2】计算机类SCI优质期刊汇总(含IEEE/Top)

一、计算机区块链类SCI-IEEE 【期刊概况】IF:4.0-5.0, JCR2区,中科院2区; 【大类学科】计算机科学; 【检索情况】SCI在检; 【录用周期】3-5个月左右录用; 【截稿时间】12.31截稿; 【接收领域】区块链…

利用idea+ jclasslib插件查看和分析 Java 类文件的字节码

jclasslib介绍 jclasslib 插件是一个用于 IntelliJ IDEA 的工具,它允许开发者在集成开发环境(IDE)内直接查看和分析 Java 类文件的字节码。这个插件尤其对于想要深入了解 Java 字节码、类加载机制、以及 Java 虚拟机(JVM&#xf…

网络基础操作练习

知识改变命运&#xff0c;技术就是要分享&#xff0c;有问题随时联系&#xff0c;免费答疑&#xff0c;欢迎联系&#xff01; 手把手教你操作华为设备&#xff0c;新手必看。 实验拓扑图 关于命令行视图 1&#xff09;用户视图 <Huawei> 2&#xff09;系统视图 [Hu…

C++初阶(类中的默认成员函数)

呀哈喽&#xff0c;我是结衣 今天给大家带来的是类里面的默认成员函数&#xff0c;一共有六个默认的成员函数哦&#xff0c;包括构造函数&#xff0c;析构函数&#xff0c;拷贝构造函数&#xff0c;运算符重载函数&#xff0c;const成员函数&#xff0c;那么正篇开始。 文章目…

Go语言中的性能考虑和优化

优化您的Go代码以达到最佳性能 性能优化是软件开发的关键方面&#xff0c;无论您使用哪种编程语言。在这篇文章中&#xff0c;我们将探讨Go语言中的性能考虑和优化&#xff0c;Go是一种以其效率而著称的静态类型和编译语言。我们将深入探讨三个关键领域&#xff1a;分析并发代…

pytorch01:概念、张量操作、线性回归与逻辑回归

目录 一、pytorch介绍1.1pytorch简介1.2发展历史1.3pytorch优点 二、张量简介与创建2.1什么是张量&#xff1f;2.2Tensor与Variable2.3张量的创建2.3.1 直接创建torch.tensor()2.3.2 从numpy创建tensor 2.4根据数值创建2.4.1 torch.zeros()2.4.2 torch.zeros_like()2.4.3 torch…

开源可观测性平台Signoz(四)【链路监控及数据库中间件监控篇】

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 前文链接&#xff1a; ​​开源可观测性平台Signoz系列&#xff08;一&#xff09;【开篇】​​ ​​开源可观测性平台Signoz&…

CSS之元素转换

我想大家在写代码时有一个疑问&#xff0c;块级元素可以转换成其他元素吗&#xff1f; 让我为大家介绍一下元素转换 1.display:block(转换成块元素) display&#xff1a;block可以把我们的行内元素或者行内块元素转换成块元素 接下来让我为大家演示一下&#xff1a; <!DO…