为什么你写的JSON.parse()总是会“莫名其妙”的报错

您所在的位置:网站首页 请求json解析失败什么意思 为什么你写的JSON.parse()总是会“莫名其妙”的报错

为什么你写的JSON.parse()总是会“莫名其妙”的报错

2023-12-03 21:25| 来源: 网络整理| 查看: 265

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情。

前言

JSON.parse()对于前端开发来说应该都不陌生了,主要是用来将已序列化的JSON字符串解析成JavaScript的值或对象,这一过程被称为反序列化。在反序列化的过程中,估计大家最不希望遇到的就是SyntaxError异常了。出现异常,则程序就会停止执行,导致页面空白或者逻辑错误。如何尽可能的避免异常呢,这就是本文要探讨的内容。JSON.stringify()就不多赘述了,感兴趣的可以移步 JSON序列化之stringify - 掘金 (juejin.cn) 。

语法

JSON.parse(text[, reviver])

参数

text:必填参数,表示要被解析成js值的JSON字符串,字符串需满足JSON规范

reviver:可选参数,如果传入该函数,则在parse函数返回前,调用该函数对解析生成的原始值做处理

返回值

返回JSON字符串对应的JavaScript值或对象

异常

如果待解析的字符串不符合JSON规范,则会抛出SyntaxError异常

JSON规范

JSON是一种语法,用来序列化对象、数组、数值、字符串、布尔值和null,它是基于JavaScript语法,但是又与之不同。也就是说Javascript不是JSON,JSON也不是Javascript,两者不可等同。为了便于梳理JSON规范的具体细则,见下表:

注:JSON字符串未说明,默认使用单引号

JSON.parse-JSON规范.png

根据如上的JSON规范表,如果传入的字符串不符合规范,则会抛出SyntaxError异常

reviver 函数

作为parse的第二个参数,如果指定reviver函数,则初步解析出来的JavaScript值或对象会经过reviver函数处理后才能最终返回。更具体点:

解析值本身以及其所包含的所有属性,会按照一定的顺序(从最里层开始,一层层向外,最终达到最顶层,也就是解析值本身)分别去调用reviver函数。在函数执行的过程中,this会指向当前属性所在的对象,当前属性名key和属性值value会作为第一个和第二个参数传入reviver函数中。如果当前函数执行返回的结果为undefined,则当前属性会从其所属的对象中删除,如果返回了其他值,则返回的值会成为当前属性新的属性值value。 当遍历到最顶层,也就是解析值时,传入reviver函数的参数将是空字符串(此时已经没有真正的属性)和当前的解析值(有可能已经被修改),此时this的值就是{"": 解析值}。因此在编写reviver函数时,需要注意此特例。 如果解析值中,有属性刚好为空字符串"",则该属性的值不会被reviver处理

举个栗子:

JSON.parse('{"x": 1, "": 2}', function(k,v) { if (k === '') return v; // 如果遇到了空字符串的key,则直接返回属性值。 return v + 1; // 其他情况,则属性值加1 }); // {x: 2, "": 2}; ​ JSON.parse('{"1": 1,"2": {"3": 3,"4": ["5", {"6": 6}]}, "7": 7}', function(k, v) { console.log(k, this); // 输出当前的属性key, return v // 返回原始值,相当于是没有处理 }) // 1 第一层对象key 1,this指向第一层对象 // 3 第二层对象key 3,this指向第二层对象 // 0 第二层对象的数组index 0,this指向数组 // 6 第三层对象key 6,this指向第三层对象 // 1 第二层对象的数组index 1,this指向数组 // 4 第二层对象key 4,this指向第二层对象 // 2 第一层对象key 2,this指向第一层对象 // 7 第一层对象key 7,this指向第一层对象 // // 最后一个属性会是一个空字符串,this指向解析值本身

一图胜千言:

JSON.parse-数据结构图.png

JSON.parse-执行过程图.png

上面两张图分别展示了数据结构和执行过程

案例

举个栗子:

JSON.parse(''); // SyntaxError,待解析的字符串不能为空 JSON.parse('{"x": 1}'); // {x: 1}, 属性必须用双引号括起来 JSON.parse('{"x": 1,}'); // SyntaxError,最后一个属性不能有逗号 JSON.parse('[1,2,]'); // SyntaxError,最后一个属性不能有逗号 JSON.parse('001'); // SyntaxError, 数字禁止有前导0 JSON.parse('11a'); // SyntaxError,不符合数值格式 JSON.parse('1.'); // SyntaxError,如果有小数点,则小数点后至少有一位数字 JSON.parse('"\n"'); // SyntaxError,控制字符不能被解析 JSON.parse(null); // null JSON.parse(undefined); // SyntaxError JSON.parse(NaN); // SyntaxError JSON.parse(Infinity); // SyntaxError 异常

使用JSON.parse()是很可能遇到抛出异常的,js遇到异常,则会停止执行后面的代码,导致页面显示不正常。一般来说处理异常有两种方式:

判断是否符合JSON规范。JSON规范还是有点多的,每个都判断不是很现实,一般判断是否为undefined以及字符串是否为空就能解决大多数不符合JSON规范的情况 使用try/catch,将可能会产生异常的JSON.parse()使用try/catch代码块包裹,并在catch中处理异常情况。 总结 使用parse可以满足将JSON字符串反序列化为JavaScript值或对象,以便于js操作 被解析的字符串需要满足JSON规范 parse可以指定第二个参数reviver,用于处理初步解析值的属性值,并返回最终对象 JSON.parse()很可能会抛出异常,建议使用try/catch代码块

原创不易,转载请注明出处。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3