JSON 详解

news2025/1/21 0:59:07

文章目录

    • 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.coloradmin.cn/o/1344589.html

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

相关文章

2023-12-30 AIGC-LangChain介绍

摘要: 2023-12-30 AIGC-LangChain介绍 LangChain介绍 1. https://youtu.be/Ix9WIZpArm0?t353 2. https://www.freecodecamp.org/news/langchain-how-to-create-custom-knowledge-chatbots/ 3. https://www.pinecone.io/learn/langchain-conversational-memory/ 4. https://de…

AJAX: 整理2:学习原生的AJAX,这边借助express框架

1. npm install express 终端直接安装 2. 测试案例:Hello World! 新建一个express.js的文件,写入下方的内容 // 1. 引入express const express require(express)// 2. 创建服务器 const app express()// 3.创建路由规则 // request 是对请…

迪杰斯特拉(Dijkstra)算法详解

【专栏】数据结构复习之路 这篇文章来自上述专栏中的一篇文章的节选: 【数据结构复习之路】图(严蔚敏版)两万余字&超详细讲解 想了解更多图论的知识,可以去看看本专栏 Dijkstra 算法讲解: 迪杰斯特拉算法(Di…

如何理解李克特量表?选项距离相等+题目权重相等!

在学术研究中,通过开展问卷调查获取数据时,调查问卷分为量表题和非量表题。量表题就是测试受访者的态度或者看法的题目,大多采用李克特量表。 李克特量表是一种评分加总式态度量表(attitude scale),由美国…

TCP/IP的五层网络模型

目录 封装(打包快递) 6.1应用层 6.2传输层 6.3网络层 6.4数据链路层 6.5物理层 分用(拆快递) 6.5物理层 6.4数据链路层 6.3网络层 6.2传输层 6.1应用层 封装(打包快递) 6.1应用层 此时做的数据…

【数字图像处理】比特平面分割,对比空间平滑滤波器的尺寸对滤波效果,对比均值滤波器和中值滤波器对图像的平滑效果

实验目的 对比均值滤波器和中值滤波器对图像的平滑效果;编程对比空间平滑滤波器的尺寸对滤波效果的影响;编程对比均值滤波器和中值滤波器对图像的平滑效果。 实验方法 比特平面分割 比特平面分层,代替突出灰度级范围,突出特定…

Unity坦克大战开发全流程——开始场景——设置界面

开始场景——设置界面 step1:设置面板的背景图 照着这个来设置就行了 step2:写代码 关联的按钮控件 监听事件函数 注意:要在start函数中再写一行HideMe函数,以便该面板能在一开始就能隐藏自己。 再在BeginPanel脚本中调用该函数即…

基于大语言模型LangChain框架:知识库问答系统实践

ChatGPT 所取得的巨大成功,使得越来越多的开发者希望利用 OpenAI 提供的 API 或私有化模型开发基于大语言模型的应用程序。然而,即使大语言模型的调用相对简单,仍需要完成大量的定制开发工作,包括 API 集成、交互逻辑、数据存储等…

为什么 export 导出一个字面量会报错而使用 export default 不会报错

核心 其实总的来说就是 export 导出的是变量的句柄(或者说符号绑定、近似于 C 语言里面的指针,C里面的变量别名),而 export default 导出的是变量的值。 需要注意的是:模块里面的内容只能在模块内部修改,…

canvas绘制红绿灯路口

无图不欢&#xff0c;先上图 使用方法&#xff08;以vue3为例&#xff09; <template><canvas class"lane" ref"laneCanvas"></canvas> </template><script setup> import { ref, onMounted } from vue import Lane from …

IDEA中允许开启多个客户端

这个时候不要在客户端里创建socket对象时指定端口号了&#xff0c;否则会报错BindException

普通人如何月入过万?2024普通人创业适合干什么?

如果你的月收入不到1万块&#xff0c;也从来没有体验过一天就赚1万块是什么感觉的话&#xff0c;你还想创业&#xff1f;你如果想通过创业逆天改命&#xff0c;麻烦你一定要看完这篇文章。 普通人你要是想赚钱&#xff0c;一定要去赚那种能看得见的钱。 什么叫看得见的钱&…

35.搜索插入位置

给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target 5 输出: 2示例 2: 输入:…

服务器运行状况监控工具

服务器运行状况监视提供了每个服务器状态和性能的广泛概述&#xff0c;通过监控服务器指标&#xff0c;如 CPU 使用率、内存消耗、I/O、磁盘使用率、进程等&#xff0c;服务器运行状况监控可以避免服务器停机。 服务器性能监控指标 服务器是网络中最重要的组件之一&#xff0…

Android studio课程设计开发实现---日记APP

Android studio课程设计开发实现—日记APP 文章目录 Android studio课程设计开发实现---日记APP前言一、效果二、功能介绍1.主要功能2.涉及知识点 三、实现思路下载链接总结 前言 你们好&#xff0c;我是oy&#xff0c;介绍一个简易日记APP。 一、效果 1.启动页、引导页及登…

【北亚服务器数据恢复】san环境下LUN Mapping出错导致文件系统一致性出错的数据恢复案例

服务器数据恢复环境&#xff1a; san环境下的存储上一组由6块硬盘组建的RAID6&#xff0c;划分为若干LUN&#xff0c;MAP到跑不同业务的服务器上&#xff0c;服务器上层是SOLARIS操作系统UFS文件系统。 服务器故障&#xff1a; 业务需求需要增加一台服务器跑新增的应用&#xf…

社区医院挂号预约服务管理系统95an6

社区医院管理服务系统具有社区医院信息管理功能的选择。社区医院管理服务系统采用p[ython技术&#xff0c;基于django框架&#xff0c;mysql数据库进行开发&#xff0c;实现了首页、个人中心、用户管理、医生管理、预约医生管理、就诊信息管理、诊疗方案管理、病历信息管理、健…

人工智能工程师的前景怎么样

人工智能是未来的发展趋势&#xff0c;因此&#xff0c;人工智能工程师也将成为就业爆款。人工智能工程师负责创建和开发自动化系统、算法和机器学习模型&#xff0c;以实现自主决策和任务执行。由于人工智能在可穿戴设备、家庭自动化、智能城市和自动驾驶等领域都有广泛应用&a…

北斗卫星助力物流企业,打造智慧运输新时代

北斗卫星助力物流企业&#xff0c;打造智慧运输新时代 北斗卫星系统作为我国自主研发的卫星导航系统&#xff0c;近年来在智慧物流领域发挥了重要作用。通过北斗卫星系统的应用&#xff0c;物流企业可以实现智能化管理&#xff0c;提高运输效率&#xff0c;降低物流成本。越来…

前端三件套html/css/js的基本认识以及示例程序

简介 本文简要讲解了html,css,js.主要是让大家简要了解网络知识 因为实际开发中很少直接写html&css,所以不必过多纠结,了解一下架构就好 希望深度学习可以参考MDN和w3school HTML 基础 HTML (Hyper Text Markup Language) 不是一门编程语言,而是一种用来告知浏览器如…