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的更多相关文章

  1. 原生js封装dom操作库

    var utils = (function(window) { var flag = "getComputedStyle" in window; function win(attr ...

  2. JS操作JSON常用方法

    一.JSON字符串的替换 工作经常遇到这样的字符串,如下: 需要经过替换后,才能从字符串转化成JSON对象.这里我们需要用JS实现replaceAll的功能, 将所有的 ' \\" ' 替换 ...

  3. 【JavaScript】使用纯JS实现多张图片的懒加载(附源码)

    一.效果图如下 上面的效果图,效果需求如下 1.还没加载图片的时候,默认显示加载图片背景图 2.刚开始进入页面,自动加载第一屏幕的图片 3.下拉界面,当一张图片容器完全显露出屏幕,即刻加载图片,替换背 ...

  4. json代码——json序列化,json-parse,JSONstringify格式化输出,虚拟DOM

    JS对象转为类似json的字符串,对象->字符串叫序列化,字符串->对象      是反序列化 ㈠json序列化 <script> var shy = new Object() ...

  5. 在 Node.js 中处理大 JSON 文件

    在 Node.js 中处理大 JSON 文件 场景描述 问题一: 假设现在有一个场景,有一个大的 JSON 文件,需要读取每一条数据经过处理之后输出到一个文件或生成报表数据,怎么能够流式的每次读取一条 ...

  6. Node.js精进(3)——流

    在 JavaScript 中,一般只处理字符串层面的数据,但是在 Node.js 中,需要处理网络.文件等二进制数据. 由此,引入了Buffer和Stream的概念,两者都是字节层面的操作. Buff ...

  7. Vue.js 和 MVVM 小细节

    MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,这使得ViewModel 的状态改变可以自 ...

  8. js学习笔记:操作iframe

    iframe可以说是比较老得话题了,而且网上也基本上在说少用iframe,其原因大致为:堵塞页面加载.安全问题.兼容性问题.搜索引擎抓取不到等等,不过相对于这些缺点,iframe的优点更牛,跨域请求. ...

  9. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

随机推荐

  1. 【题解】 CF767E Change-free

    洛谷链接 这个题翻译忘了输入,我看的英语原文...... 首先,这是一道贪心题 我的大致方法:pair+堆优 题目分析: 从第一天开始,到最后一天,每天可以选择找钱或者不找钱. 如果不找钱,则零钱数m ...

  2. Docker --volume(数据持久化)

    数据卷 volume 数据卷 是一个可供一个或多个容器使用的特殊目录,实现让容器中的一个目录和宿主机中的一个文件或者目录进行绑定.数据卷 是被设计用来持久化数据的 第一种:bind mount vol ...

  3. JVM调优之垃圾定位、垃圾回收算法、垃圾处理器对比

    谈垃圾回收器之前,要先讲讲垃圾回收算法,以及JVM对垃圾的认定策略,JVM垃圾回收器是垃圾回收算法的具体实现,了解了前面的前置知识,有利于对垃圾回收器的理解. 什么是垃圾? 垃圾,主要是指堆上的对象, ...

  4. WPF 之 依赖属性与附加属性(五)

    一.CLR 属性 ​ 程序的本质是"数据+算法",或者说用算法来处理数据以期得到输出结果.在程序中,数据表现为各种各样的变量,算法则表现为各种各样的函数(操作符是函数的简记法). ...

  5. Codeforces Round #627 (Div. 3) F - Maximum White Subtree(深度优先搜索)

    题意: n 个点 n - 1 条边的树,问每个点所在所有子树中白黑点数目的最大差. 思路: 白点先由下至上汇集,后由上至下分并. #include <bits/stdc++.h> usin ...

  6. HDU6434 Count【欧拉函数 线性筛】

    HDU6434 I. Count T次询问,每次询问\(\sum_{i=1}^{n}\sum_{j=1}^{n-1}[gcd(i-j,i+j)=1]\) \(T\le 1e5, n \le 2e7\) ...

  7. HDU 1173 思路题

    题目大意 有n个地点(坐标为实数)需要挖矿,让选择一个地点,使得在这个地方建造基地,到n个地点的距离和最短,输出基地的坐标. 题解+代码: 1 /* 2 把这个二维分开看(即把所有点投影到x轴上,再把 ...

  8. nuoyanli 520 Let‘s play computer game

    H题 描述 xxxxxxxxx在疫情期间迷上了一款游戏,这个游戏一共有nnn个地点(编号为1--n1--n1--n),他每次从一个地点移动到另外一个地点需要消耗 一定的能量,每一个地点都有一些珠宝,输 ...

  9. Educational Codeforces Round 89 (Rated for Div. 2) C. Palindromic Paths (思维)

    题意:有一个\(n\)x\(m\)的矩阵,从\((1,1)\)出发走到\((n,m)\),问最少修改多少个数,使得所有路径上的数对应相等(e.g:\((1,2)\)和\((n-1,m)\)或\((2, ...

  10. vlc音视频开发(二)环境搭建(VS篇)

    来源:微信公众号「编程学习基地」 目录 简介 VS配置vlc开发环境 下载vlc源码 创建vlc环境 测试vlc代码 运行vlc程序 完成项目文件获取 简介 VLC 是一款自由.开源的跨平台多媒体播放 ...