优秀的编程知识分享平台

网站首页 > 技术文章 正文

异常JSON字符串的解析以及JS字符串的解析运行

nanyue 2024-08-01 22:43:06 技术文章 7 ℃

一个常见的面试题,经常会遇到key没有引号或者使用的单引号的JSON字符串解析问题。

把下面字符串解析为对象。

var str = "{a: 1, 'b': 2}";

或者就是面试题的刁钻要求,不适用JSON.parse如何解析JSON字符串。

这个简单,eval呗,要是eval也不能用呢?或许有人还会想到new Function。然而,对于JS字符串解析运行是有N种方式的。下面为了方便运行查看我们直接解析"console.log('abc')"字符串。

这里就不再说eval和new Function了。

[native code].constructor

所谓[native code]是指那些不是通过JS封装的函数,例如数组的push,slice等等...

[].push.constructor('console.log("abc");')(); // abc

Math.max.constructor('console.log("abc");')(); // abc

但是这个和new Function一个意思。

[].push.constructor === Function // true

动态插入script标签

var script = document.createElement('script');

var txt = document.createTextNode('console.log("abc");');

script.appendChild(txt);

document.body.appendChild(script); // abc

当让,也可以通过把字符串转化为二进制然后通过window.URL.createObjectURL生成URL修改script的src。

var blob = new Blob(['console.log("abc");']);

var src = window.URL.createObjectURL(blob);

var script = document.createElement('script');

script.src = src;

document.body.appendChild(script); // abc

webWorker

上面已经生成了url,那么我们可以直接在worker中运行。

var blob = new Blob(['console.log("abc");']);

var src = window.URL.createObjectURL(blob);

new Worker(src); // abc

当然,这里只是在worker中运行的,如果是JSON解析结果还需要通过postMessage返回出来。

location.href=javascript:

javascript:都经常在a标签的href中或则onclick中用到,不过有人去研究过直接在浏览器地址栏输入运行没有。javascript:alert(),可以看到,页面会直接执行后面的字符串。而且页面不会发生跳转。

location.href='javascript:' + 'console.log("abc")'; // abc

当然,如果你有更好的方式欢迎留言。

小技巧

说到这里想到前面两天在知乎首页看到有人分享的UC面试题。其中有一道题不使用循环生成[1,2,3,4...]长度100的数组。

当然,解题方式很多,递归,setInterval,Array.from都可以办到。既然在这里提出来,就来说一个新奇的思路。

var str = 'var i = 0; var arr = [i++, i++, i++]';

eval(str);

console.log(arr); // [0,1,2]

看到这里不知道有人受到启发没有,我们可以生成这样一个字符串通过eval或则上面任意一种方式去解析。当然,为了更友好的显示,这里生成长度为5示例一下就OK了。

var str = new Array(6).join('i++,'); // 'i++,i++,i++,i++,i++,'

// var str = 'i++,'.repeat(5) 当然,这样写也OK

注意卫生么长度为5这里new Array要用6,join是在每两个item中间拼接,而对于稀疏数组来说,自生值为undefined就不会拼接上去。

和上面示例字符串比较,还差什么?i的声明以及数组的方括号。

var evalstr = 'var i = 0; var arr = [' + str + ']';

eval(evalstr);

console.log(arr); // [0, 1, 2, 3, 4, 5]

最近发表
标签列表