为什么eval里面要加圆括号?
原文链接 http://judes.me/frontend/2014/05/18/eval-why.html
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。
最近在 JavaScript DOM 高级程序设计上看到这样一段代码:
try {
j = eval('(' + s + ')')
} catch(e){
throw new SyntaxError("parseJSON");
}
为什么eval内部的 s 要用圆括号围起来呢?
书上的解释:因为 s 是JSON格式的数据,形式是这样的:{key1:val1,key2:val2}
,其中“{”操作符具有语法上的二义性:它既可以定义一个语句块,也可以表示对象字面量,用圆括号围起来是让它表示对象字面量。
如果要深入了解背后的原理,就要先知道几个概念:语句、表达式及分组操作符。
以下内容引自代码之谜(二)- 语句与表达式:
"表达式"(expression)是一个单纯的运算过程,总是有返回值;
"语句"(statement)是执行某种操作,没有返回值。
表达式的特点:
- 会返回一个值
- 可放在任何一个需要值的地方
- 存在于表达式上下文当中
- 表达式的一部分也是表达式
- 表达式可以代替(本该出现的)语句,此时的表达式称为表达式语句
语句的特点:
- 不会返回值
- 存在于语句上下文中
- 语句不能代替(本该出现的)表达式,例如不能把语句作为函数的参数
圆括号:(),是分组操作符,分组操作符只能包含表达式。
还需要知道的一点是,eval会将其参数放进 语句上下文 中解释。
我们要传进eval中解释的是一个对象字面量,是一个值。所以要传进去的是一个表达式,如果不加圆括号,这个表达式就会被解释成表达式语句,圆括号可在语句上下文内产生新的一个表达式上下文来避免这一点。
参考文献