为什么eval转换json对象字符串时要加括号?

在做与服务器交互数据的时候,我们通常会发起一个Ajax请求,然后服务器返回一个类似'{x:1,y:1}'结构的json字符串,为了方便客户端处理我们会将其转换为一个对象直接量,这很多的时候通过一个eval来实现 。

var jsonstr = '{x : 1, y : 1}';
var jsonobj = eval('(' + jsonstr + ')');

如果eval的时候不加括号还会报脚本错误,这是为什么呢?

因为eval中 是一个执行环境,当你不用括号的时候{x : 1, y : 1}整个被解释成一个复合语句,{和}在这里就是一个符合语句的分隔符,而不是我们原本认为的对象直接量的一种语法方式。就像我们通常写if(true){x=1;}这里的大括号也是充当着复合语句的作用。接下来x:被解释成标签,像通常用的swicth case语句中的case x:也是一种标签,至于标签的其他用法可以参考相关资料。后面的1被当做一个数字直接量,遇到y被解释成变量标示符,然后再继续解析y后的冒号时就出错了,因为无法识别。所以如果你写成eval('{x : 1, y = 1}')就不会报错了,因为y=1是可以被识别的, y=1后eval的结果是返回1。但是为什么前后加个括号就可以了呢,因为括号在这里表示强制执行,整个'(' +  jsonStr + ')'其实被解释成一个表达式运算,而不是一个复合语句,因此jsonStr中的大括号{}被当成对象的语法来识别,当然就可以了。


说完了上面,我们再来看一个例子,如果我们写eval('{x:1}')这样呢,这会报错吗?
答案是不会,因为虽然{x:1}被认为是一个复合语句,但是x:1这样的写法是没错的,当做标签来识别,因此结果返回1 ,说白了只要让{……}所表示的复合语句不让解析不能理解就可以了,如{x:1, y=1,z=6}不会报错,返回最后的结果6。


PS:当服务器返回的为json数组字符串的结构时 如:"[{x:1,y:2}]",直接使用eval()进行转换是没有问题的。

var josnstr = "[{x:1,y=2}]";
var jsonarr = eval(jsonstr);


你可能感兴趣的:(Javascript)