《javascript高级程序设计》学习笔记 | 23.JSON

关注[前端小讴],原创技术文章

JSON

  • JSON 是 JS 对象简谱,是一种通用的数据格式
  • 和 JS 有相同的语法,但不属于 JS,很多语言都能解析和序列化 JSON

相关代码 →

语法

  • JSON 支持 3 种类型的值
    • 简单值:字符串、数值、布尔值、null,undedined 不可以
    • 对象:复杂数据类型,有序键/值对,每个值可以是简单值/复杂类型
    • 数组:复杂数据类型,通过数值索引访问的值的有序列表,每个值可以是任意类型

简单值

  • 可以是一个数值
5
  • 可以是一个字符串,与 JS 字符串的区别在于,必须使用双引号(单引号会导致语法错误)
"1"
  • 可以是布尔值、null,但不能是 undefined

对象

  • 与 JS 字面量的区别在于,属性名必须使用双引号
    • 还有 2 处不同在于,没有变量声明末尾无分号
// js字面量
let person = {name: "Nicholas",age: "29",
};
// json对象
{"name": "Nicholas","age": "29"
}
  • 属性的值也可以是复杂数据类型
{"name": "Nicholas","age": "29","school": {"name": "m college","lacation": "a street"}
}

数组

  • 与 JS 数组的区别在于,没有变量声明末尾无分号
// js数组
let values = [25, "hi", true];
// json数组
[25, "hi", true]
  • 数组和对象可以组合使用,以表示更复杂的数据结构
[{"name": "Nicholas","age": "29","school": {"name": "m college","lacation": "a street"}},{"name": "Matt","age": "27","school": {"name": "n college","lacation": "b street"}}
]

解析与序列化

JSON 对象

  • JSON 对象有 2 个方法

    • **stringify()**将 js 序列化为 JSON 字符串
    let book = {title: "Professional",authors: ["Nicholas", "Matt"],edition: 4,year: 2017,
    };
    let jsonText = JSON.stringify(book);
    console.log(jsonText); // {"title":"Professional","authors":["Nicholas","Matt"],"edition":4,"year":2017}
    
    • **parse()**将 JSON 字符串解析为原生 js 值
    let bookCopy = JSON.parse(jsonText);
    let bookCopy = JSON.parse(jsonText);
    console.log(bookCopy);
    /* 
    {title: 'Professional',authors: [ 'Nicholas', 'Matt' ],edition: 4,year: 2017
    }
    */
    
    • 可一并使用JSON.stringify()JSON.parse()进行对象深拷贝
    let bookCopy2 = JSON.parse(JSON.stringify(book)); // 深拷贝
    console.log(bookCopy2);
    
  • 序列化 JS 对象时,所有函数、原型成员、值为 undefined的属性会在结果中省略

let book2 = {title: "Professional",authors: ["Nicholas", "Matt"],edition: () => {}, // 序列化时会被省略year: undefined, // 序列化时会被省略
};
let jsonText2 = JSON.stringify(book2);
console.log(jsonText2); // {"title":"Professional","authors":["Nicholas","Matt"]}
let bookCopy3 = JSON.parse(jsonText2);
console.log(bookCopy3);
/* 
{ title: 'Professional',authors: [ 'Nicholas', 'Matt' ]
}
*/

序列化选项

  • JSON.stringify()接受 2 个参数:过滤器用于缩进结果 JSON 字符串的选项

    • 第 2 个参数数组,返回只包含该数组中列出的对象属性
    let jsonText3 = JSON.stringify(book, ["title", "edition"]); // 只返回包含title和edition属性
    console.log(jsonText3); // {"title":"Professional","edition":4}
    
    • 第 2 个参数函数,函数接受 2 个参数 key 和 value,根据 key 决定要对应属性执行的操作
    let jsonText4 = JSON.stringify(book, (key, value) => {switch (key) {case "authors":return value.join(","); // 将数值转换为字符串case "year":return 5000; // 返回5000case "edition":return undefined; // 忽略该属性default:return value; // 必须设置默认返回值}
    });
    console.log(jsonText4); // {"title":"Professional","authors":"Nicholas,Matt","year":5000}
    
    • 函数过滤器会应用到要序列化对象所包含的所有对象
    let book3 = {title: "Professional",authors: ["Nicholas", "Matt"],edition: 4,year: 2017,book3: {title: "Professional2",authors: ["Nicholas", "Matt"],edition: 4,year: 2017,}, // 对book3做序列化时,内层的book3对象同样受影响
    };
    let jsonText5 = JSON.stringify(book3, (key, value) => {switch (key) {case "authors":return value.join(",");case "year":return 5000;case "edition":return undefined;default:return value;}
    });
    console.log(jsonText5); // {"title":"Professional","authors":"Nicholas,Matt","year":5000,"book3":{"title":"Professional2","authors":"Nicholas,Matt","year":5000}}
    
  • JSON.stringify()的第 3 个参数控制缩进和空格,且所有有效缩进都插入换行符

    • 第 3 个参数数值,表示每级缩进的空格数(最大为 10,大于 10 自动为 10)
    let jsonText6 = JSON.stringify(book, null, 4); // 每级缩进4个空格
    console.log(jsonText6);
    /* 
    {"title": "Professional","authors": ["Nicholas","Matt"],"edition": 4,"year": 2017
    }
    */
    
    • 第 3 个参数字符串,表示使用该字符串缩进
    let jsonText7 = JSON.stringify(book, null, "-"); // 使用'-'缩进
    console.log(jsonText7);
    /* 
    {
    -"title": "Professional",
    -"authors": [
    --"Nicholas",
    --"Matt"
    -],
    -"edition": 4,
    -"year": 2017
    }
    */
    
  • 可在要序列化对象中添加 toJSON()方法,使用 JSON.stringify()方法序列化时则自动适当的 JSON 表示

    let book4 = {title: "Professional",authors: ["Nicholas", "Matt"],edition: 4,year: 2017,toJSON: function () {return this.title; // 执行toJSON(),返回值直接return},
    };
    let jsonText8 = JSON.stringify(book4);
    console.log(jsonText8); // "Professional"
    
    • 箭头函数不能定义 toJSON() 方法,因为其作用域是全局作用域
    • toJSON() 可与过滤函数一并使用:① 调用 toJSON()获取实际返回值(如没有则使用默认的序列化) ② 将该值传入过滤函数
    let num = {toJSON: function () {return 123;},
    };
    let book5 = {title: "Professional",authors: ["Nicholas", "Matt"],edition: 4,year: 2017,num,
    };
    let jsonText9 = JSON.stringify(book5, ["title", "edition", "num"], 4); // JSON.stringify()时默认调用num的toJSON()方法
    console.log(jsonText9);
    /* 
    {"title": "Professional","edition": 4,"num": 123
    }
    */
    

解析选项

  • JSON.parse() 接受一个还原函数,函数接受 2 个参数 key 和 value,根据 key 决定要对应属性执行的操作
let book6 = {title: "Professional",authors: ["Nicholas", "Matt"],edition: 4,year: 2017,num,
};
let jsonText10 = JSON.stringify(book6);
let bookCopy4 = JSON.parse(jsonText10, (key, value) =>key === "year" ? value + 1 : value
);
console.log(bookCopy4);
/* 
{title: 'Professional',authors: [ 'Nicholas', 'Matt' ],edition: 4,year: 2018,num: 123
}
*/
  • 与 JSON.stringify()第 2 个参数为函数时相似,返回值为undefined的建将被忽略
let bookCopy5 = JSON.parse(jsonText10,(key, value) => (key === "year" ? undefined : value) // 返回值为undefined的建将被忽略
);
console.log(bookCopy5);
/* 
{title: 'Professional',authors: [ 'Nicholas', 'Matt' ],edition: 4,num: 123
}
*/

总结 & 问点

  • JSON 支持哪些类型的值?各种类型相比 JS 分别有哪些不同的语法?
  • 如何利用 JSON 序列化进行深拷贝?哪些情况下序列化后对象的属性会被省略?
  • JSON.stringify()的第二个参数为数组或函数时,分别对结果进行了怎样的过滤?
  • JSON.stringify()的第三个参数为数值或字符串时,分别对结果进行了怎样的缩进?
  • 写一段代码,使用 toJSON()结合过滤函数对 JSON 进行序列化
  • 写一段代码,利用 JSON.parse()的第二个参数(还原函数)进行字符串解析

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

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

相关文章

leetCode刷题 4.寻找两个正序数组的中位数

目录 1. 思路 2. 解题方法 3. 复杂度 4. Code 题目: 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (mn)) 。 示例 1: 输入&…

1分钟带你搞定Python函数分类

python语言中,函数可以分为内置函数、自定义函数、有参数函数、无参数函数、有名字函数和匿名函数。其中,内置函数可以直接使用,自定义函数需要根据需求定义。有参数函数在定义时需要指定参数,调用时传入参数。无参数函数在定义时…

python基础 — 进制转换

1、进制引导符号 在 Python 中,可以使用不同的前缀(引导符号)来表示不同的进制。 以下是各种进制的引导符号: 二进制(Binary):使用0b或0B作为前缀。例如:0b1010 表示二进制数 101…

SpringBoot 跨域配置

SpringBoot 跨域配置 添加配置文件 Configuration public class CorsConfig {private CorsConfiguration buildConfig() {CorsConfiguration corsConfiguration new CorsConfiguration();corsConfiguration.setAllowCredentials(true);// 设置访问源地址corsConfiguration.a…

git远程仓库使用

赋值这个地址clone 克隆之后 cd slam_oncloud/ git remote add chenxnew ssh://git192.168.3.40:1022/chenxiao/slam_oncloud.git 查看一下 linuxchenxiao:/media/linux/mydisk/cloud_slam/slam_oncloud$ git remote add chenxnew ssh://git192.168.3.40:1022/chenxiao/sla…

记录一次Dubbo远程调用的错误

情景:有一个生成PDF的接口中,如下: GET Path("/getPDF") public void getPDF(QueryParam("id") String id, Context HttpServletResponse response) {………… }之前实现的代码都写在了Controller里面,代码里…

【算法笔记】LeetCode_15_三数之和

LeetCode_15_三数之和 LeetCode 15 (LeetCode 15) 题目描述 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复…

北斗卫星助力无人机在沙漠播种,促进沙漠治理

北斗卫星助力无人机在沙漠播种,促进沙漠治理 近年来,随着科技的不断发展,北斗卫星和无人机技术的结合被广泛应用于沙漠治理领域,为解决沙漠化问题提供了全新的思路和解决方案。 近日,黄河“几字弯”北岸的内蒙古自治…

《LeetCode力扣练习》代码随想录——二叉树(完全二叉树的节点个数---Java)

《LeetCode力扣练习》代码随想录——二叉树(完全二叉树的节点个数—Java) 刷题思路来源于 代码随想录 222. 完全二叉树的节点个数 二叉树-后序遍历 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeN…

[力扣100][好题] 121.买股票的最佳时机 || 动态规划

添加链接描述 思路: 设置一个动态数组dp用来存放当前最大的利润这个利润有两个来源:来源一是来自上一个最大利润;来源二是目前值减去最小买入价格如何维护最小值?预设一个最小值然后将这个最小值每次和当前值比较 class Solutio…

word打字后面的字消失是怎么回事

在使用Microsoft Word进行文档编辑时,很多用户可能会遇到一个令人困惑的问题:当在文档中打字时,后面的字却莫名其妙地消失了。这种情况不仅影响了编辑效率,还可能导致重要数据的丢失。那么,这一现象背后的原因是什么&a…

JVM3_数据库连接池虚引用ConnectionFinalizerPhantomReference引起的FullGC问题排查

背景 XOP服务运行期间,查看Grafana面板,发现堆内存周期性堆积,Full GC时间略长,需要调查下原因 目录 垃圾收集器概述 常见的垃圾收集器分区收集策略为什么CMS没成为默认收集器 查看JVM运行时环境分析快照 PhantomReference虚引用…

46. 全排列(力扣LeetCode)

文章目录 46. 全排列题目描述回溯算法 46. 全排列 题目描述 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1: 输入:nums [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],…

深度学习目标检测】二十二、基于深度学习的肺炎检测系统-含数据集、GUI和源码(python,yolov8)

肺炎尽管很常见,但准确诊断是一项困难的任务。它要求训练有素的专家对胸部X光片进行检查,并通过临床病史,生命体征和实验室检查进行确认。肺炎通常表现为胸部X光片上一个或多个区域的阴影(opacity)增加。但是,由于肺部有许多其他状…

每日OJ题_链表①_力扣2. 两数相加

目录 力扣2. 两数相加 解析代码 力扣2. 两数相加 2. 两数相加 难度 中等 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。 请你将两个数相加,并以相同形式返回一个…

【Python】创建python库的学习笔记

1. 约定俗成的目录结构 根目录下的setup.py:在根目录下包含一个setup.py文件,用于指定项目的依赖关系、包信息以及其他安装和分发相关的元数据。例如,pyminitouch/setup.py。与库同名的代码目录:建立与库同名的代码文件夹&#x…

二维码门楼牌管理系统应用场景:数据管理的智慧新选择

文章目录 前言一、数据管理部门的智慧工具二、助力决策制定与优质服务提供三、二维码门楼牌管理系统的优势四、展望未来 前言 随着科技的飞速发展,二维码门楼牌管理系统正逐渐成为城市管理的智慧新选择。该系统不仅提升了数据管理效率,还为政府和企业提…

linux中怎么用shell逐行读取文件

在Linux中,可以使用shell脚本逐行读取文件。有多种方法可以实现这个功能,下面是几个常见的方法: 方法一:使用while循环和read命令逐行读取文件 #!/bin/bash file="filename.txt" while IFS= read -r line doecho "$line" done < "$file"…

python并发编程:阻塞IO

阻塞IO&#xff08;blocking IO&#xff09; 在Linux中&#xff0c;默认情况下所有的socket都是blocking&#xff0c;一个典型的读操作流程大概是这样&#xff1a; 当用户进程调用了recvfrom这个系统调用&#xff0c;kernel就开始了IO的第一个阶段&#xff1a;准备数据。对于…

[编码] Base64基础知识

文章目录 Base64编码解码原理参考 Base64编码解码原理 首先有一个64个字符的转换表。 待转转换的数据&#xff0c;3个字节位一组&#xff0c;3个字节24位&#xff0c;刚好可以分成4个6位的对象&#xff0c; 每个6位对象前补2个0&#xff0c;就变成了4个字节。这就可以对应转换…