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.hqwc.cn/news/310573.html

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

相关文章

【逗老师的无线电】ICOM IC-705终端模式Terminal Mode直连反射器配置-外置Pi-Star网关篇

各位友台大家好呀,逗老师最近整了一台IC-705,最吸引人的莫过于这玩意可以通过USB连接树莓派直接进行通联。下面简单介绍一下这个功能和其配置方法 一、功能 终端模式Terminal Mode允许IC-705电台作为终端直接连接反射器,基于不同的连接方式…

纯CSS3制作优惠券线性UI效果

纯CSS3制作优惠券线性UI效果-遇见你与你分享

java并发编程一 并发编程的基本概念

进程与线程 进程 程序由指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载至 CPU,数据加载至内存。在指令运行过程中还需要用到磁盘、网络等设备。进程就是用来加载指令、管理内存、管理 IO 的当一个程序被运行&…

C# 如何使用?、? 和 ??的区别和使用案例

目录 ? 运算符 使用案例 ?? 运算符 使用案例 总结 在 C# 中,? 和 ?? 运算符在处理 null 值时起着不同的作用,并且具有特定的使用场景。 ? 运算符 ? 运算符,也称为空条件运算符,在 C# 6.0 及更高版本中引入。它允许…

关于“Python”Django 管理网站的核心知识点整理大全52

目录 注意 18.2.2 激活模型 settings.py 18.2.3 Django 管理网站 1. 创建超级用户 注意 2. 向管理网站注册模型 admin.py 注意 3. 添加主题 Climbing。 18.2.4 定义模型 Entry models.py 18.2.5 迁移模型 Entry 18.2.6 向管理网站注册 Entry admin.py 往期快速…

fastjosn利用分析

fastjosn一般是使用TemplatesImpl链来进行攻击的,在上面其实已经分析过fastjson在反序列化的时候会调用满足条件的getter方法,因此就会调用TemplatesImpl类的getOutputProperties方法,然后通过getOutputProperties,调用newTransfo…

Qt QAction添加图片

QAction用的时候,时常需要添加图片,如上图所示,代码如下所示: 测试的图片格式包含png,jpg,bmp,svg,其他未测试

Solidworks学习笔记

本内容为solidworks的学习笔记,根据自己的理解进行记录,部分可能不正确,请自行判断。 学习视频参考:【SolidWorks2018视频教程 SW2018中文版软件基础教学知识 SolidWorks自学教程软件操作教程 sw视频教程 零基础教程 视频教程】 h…

【GOLANG】使用插件 Goanno 的方式来对方法、接口、结构体注释模板配置

直接 使用插件 Goanno 的方式来对方法、接口、结构体注释模板配置 1、简单安装 Goanno 插件 File->Settings->Plugins , 搜索 Goanno Normal Method 配置内容如下: // Title ${function_name} // Description ${todo} // Author mumu ${date} ${time} // Par…

Ps:亮度蒙版 - 多层级 Alpha 通道方法

本文主要介绍创建高光、阴影、中间调选区的方法,并可基于它们创建更多层级的 Alpha 通道,从而根据需要自由地创建亮度蒙版。 应用视频演示 以下方法中,依据高光、阴影及中间调各创建三个层次的 Alpha 通道,总共九个 Alpha 通道可用…

华为交换机生成树STP配置案例

企业内部网络怎么防止网络出现环路?学会STP生成树技术就可以解决啦。 STP简介 在二层交换网络中,一旦存在环路就会造成报文在环路内不断循环和增生,产生广播风暴,从而占用所有的有效带宽,使网络变得无法正常通信。 在…

探索 Pinia:简化 Vue 状态管理的新选择(下)

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