js jsonParse
const rx_one = /^[\],:{}\s]*$/;
const rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
// 匹配合法json符号
// "asd" or 1.23 or 1.3e4 or 1.3e-4 or 1.3e+4 or -10 之类的
const rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
// :[
// ,[
const rx_four = /(?:^|:|,)(?:\s*\[)+/g;
// 一些符号的unicode表示法
const rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
export function jsonParse(text: string, reviver?: Function): any {
// 接受一个文本和一个可选的reviver函数,然后返回
// 如果文本是有效的JSON文本,则为JavaScript值
let j;
function walk(holder: any, key: any) {
// walk方法用于递归遍历结果结构,因此可以进行修改。
let k: string | number;
let v: any;
let value = holder[key];
if (value && typeof value === "object") {
// {} or []
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
}
return reviver?.call(holder, key, value);
}
}
// 解析分为四个阶段。 在第一阶段,我们替换某些
// 具有转义序列的Unicode字符。 JavaScript处理许多字符
// 错误地将其静默删除,或将其视为行尾。
text = String(text);
rx_dangerous.lastIndex = 0;
if (rx_dangerous.test(text)) {
// 转义序列的Unicode字符
text = text.replace(rx_dangerous, function(match) {
return "\\u" + ("0000" + match.charCodeAt(0).toString(16)).slice(-4);
});
}
// 在第二阶段,我们针对看起来像正则表达式的文本
// 用于非JSON模式。 我们特别关注"()"和"new"
// 因为它们会引起调用,而"="则可能导致突变
// 但是为了安全起见,我们要拒绝所有意外的形式。
// 为了解决此问题,我们将第二阶段分为4个正则表达式操作
// 严重影响IE和Safari的regexp引擎的效率低下。 首先我们
// 将JSON反斜杠对替换为"@"(非JSON字符)。 第二,我们
// 用"]"字符替换所有简单值标记。 第三,我们删除所有
// 用冒号或逗号或文本开头的方括号。 最后,
// 我们希望看到其余字符只是空格或"]"或
// "."或":"或"{"或"}". 如果是这样,那么该文本对于eval是安全的。
if (
rx_one.test(
/*`{"name": "ajanuw"}` => `{]: ]}` */
text
.replace(rx_two, "@")
.replace(rx_three, "]")
.replace(rx_four, "")
)
) {
// 在第三阶段,我们使用eval函数将文本编译为
// JavaScript结构。 "{"运算符存在句法歧义
// 在JavaScript中:它可以开始一个块或一个对象文字。 我们包装文字
// 尽可能消除歧义
j = eval(`(${text})`);
// 在可选的第四阶段,我们递归遍历新结构,
// 每个名称/值对到reviver函数进行可能的转换
return typeof reviver === "function"
? walk(
{
"": j
},
""
)
: j;
}
// 如果文本不是JSON可解析的,则抛出SyntaxError。
throw new SyntaxError("json parse error!!");
}
const r = jsonParse(`{"name": "ajanuw"}`);
console.log({ result: r });
js jsonParse的更多相关文章
- 原生js封装dom操作库
var utils = (function(window) { var flag = "getComputedStyle" in window; function win(attr ...
- JS操作JSON常用方法
一.JSON字符串的替换 工作经常遇到这样的字符串,如下: 需要经过替换后,才能从字符串转化成JSON对象.这里我们需要用JS实现replaceAll的功能, 将所有的 ' \\" ' 替换 ...
- 【JavaScript】使用纯JS实现多张图片的懒加载(附源码)
一.效果图如下 上面的效果图,效果需求如下 1.还没加载图片的时候,默认显示加载图片背景图 2.刚开始进入页面,自动加载第一屏幕的图片 3.下拉界面,当一张图片容器完全显露出屏幕,即刻加载图片,替换背 ...
- json代码——json序列化,json-parse,JSONstringify格式化输出,虚拟DOM
JS对象转为类似json的字符串,对象->字符串叫序列化,字符串->对象 是反序列化 ㈠json序列化 <script> var shy = new Object() ...
- 在 Node.js 中处理大 JSON 文件
在 Node.js 中处理大 JSON 文件 场景描述 问题一: 假设现在有一个场景,有一个大的 JSON 文件,需要读取每一条数据经过处理之后输出到一个文件或生成报表数据,怎么能够流式的每次读取一条 ...
- Node.js精进(3)——流
在 JavaScript 中,一般只处理字符串层面的数据,但是在 Node.js 中,需要处理网络.文件等二进制数据. 由此,引入了Buffer和Stream的概念,两者都是字节层面的操作. Buff ...
- Vue.js 和 MVVM 小细节
MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,这使得ViewModel 的状态改变可以自 ...
- js学习笔记:操作iframe
iframe可以说是比较老得话题了,而且网上也基本上在说少用iframe,其原因大致为:堵塞页面加载.安全问题.兼容性问题.搜索引擎抓取不到等等,不过相对于这些缺点,iframe的优点更牛,跨域请求. ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
随机推荐
- Maven环境搭建以及在IDEA中的配置与简单入门
目录 一.下载与安装 二.配置 1. 环境变量 2. 阿里云镜像 3. 本地仓库 三.IDEA创建Maven项目 1. 创建一个原始的Maven项目 1.2 指定模板创建(可选) 2. 配置GAV 3 ...
- XSS、CSRF、SSRF联系&区别,防御
目录 区别和联系 防御 联系和区别 相同点: XSS,CSRF,SSRF三种常见的Web服务端漏洞均是由于,服务器端对用户提供的可控数据过于信任或者过滤不严导致的. 相同点: XSS,CSRF,SSR ...
- ScalikeJDBC,操作mysql数据,API
ScalikeJDBC,操作mysql数据,API 一.构建maven项目,添加pom.xml依赖 二.resource文件下创建application.conf文件,并配置以下内容 三.操作mysq ...
- redis防止重复提交
public interface DistributedLock { boolean getLock(String var1, String var2, int var3);//加锁 void unL ...
- apache和LAMP架构
资源池: httpd依赖包:apr 和 apr-util 下载:点击这里 httpd 下载:点击这里 mysql 下载:点击这里 php 下载: 点击这里 本章资源: 点击这里 资源提取码:u2jv ...
- 2.二层常用技术-Portfast和BPDU Guard、BPDU Filter
PortFast (生成树端口加速) 1.在交换机上使用portfast命令,可以防止出现由于STP的收敛时间太长,导致主机的DHCP请求超时,从而使主机不能接收到DHCP地址的问题. 确保有一台服务 ...
- Linux和Xshell安装
Linux安装 开启虚拟机 选择语言 软件选择 点击软件→软件选择→基础设施服务器 安装位置 网络连接 开始安装 设置root密码 建议设置成root,因为密码忘了改起来很麻烦 登录 查看IP Xsh ...
- Neo4j 导入 Nebula Graph 的实践总结
摘要: 主要介绍如何通过官方 ETL 工具 Exchange 将业务线上数据从 Neo4j 直接导入到 Nebula Graph 以及在导入过程中遇到的问题和优化方法. 本文首发于 Nebula 论坛 ...
- 2018-2019 ACM-ICPC Brazil Subregional Programming Contest PART (10/13)
$$2018-2019 ACM-ICPC Brazil Subregional Programming Contest$$ \(A.Slackline\ Adventure\) \(B.Marbles ...
- hdu5438 Ponds
Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total Submissi ...