Quickeryi / note

学习记录
2 stars 0 forks source link

javascript高级程序设计: JSON补充 #30

Open Quickeryi opened 7 years ago

Quickeryi commented 7 years ago

之前已经有了一片关于JSON对象的文章了,这篇笔记记录一个常见的问题,关于JSON字符串的解析方法。

对于ES5之后的JS版本,直接可以使用原生的parse即可

eval

最为开发人员熟知的解析JSON String的兼容方法就是eval,下面将探讨从两个问题:

eval是为何可以解析JSON String

eval接受字符串参数,解析其中的js代码,如果传人的参数的是表达式,则会计算后返回。

let jsonstr = '{ "age": 20, "name": "jack" }';
eval(`(${jsonstr})`);

可能已经注意到了,参数中有一对()这是为何呢?因为js{}通常是表示一个语句块,eval只会计算语句块内的值进行返回,加上括号就变成一个整体的表达式。

eval存在的问题

大概很多人都知道要慎用eval,这又是为何呢?因为eval可以创建局部变量,改变局部上下文

var c = 1;
(function(){
    var c = 2;
    eval('var c = 3;')
    console.log('c1:', c) // c1: 3
}());
console.log('c2:', c)// c2: 1

eval的优点?

可能很多人被大量的负面文章影响,觉得eval函数是一个不应该存在的存在,其实eval在某些场景有其独特的作用,我这我就不讨论了,其实自己也是没彻底理解透彻。但是请记住,凡事存在的就有它存在的道理。

Function

相对于使用eval解析JSON字符串,更加建议使用Function来做,因为它相对来说更加安全一些

使用Function构造器生成的函数,并不会在创建它们的上下文中创建闭包;它们一般在全局作用域中被创建。当运行这些函数的时候,它们只能访问自己的本地变量和全局变量,不能访问Function构造器被调用生成的上下文的作用域。这和使用带有函数表达式代码的 eval 不同

var c = 1;
(function(){
    var c = 2;
    Function('var c = 3; console.log("c1:", c)')() // c1: 3
    console.log('c2:', c) // c2: 2
}());
console.log('c3:', c) //c3: 1

// 解析  json string
let jsonstr = '{ "age": 20, "name": "jack" }';
Function(`return ${ jsonstr}`)()

课后阅读