eval()是否首先对计算字符串进行字面翻译?

时间:2013-07-02 20:00:11

标签: javascript json eval quotes

尝试在浏览器中执行以下代码:

eval("(function() { console.log(JSON.parse('" + JSON.stringify('THIS IS COOL') + "')); })()");

它应打印出THIS IS COOL, 但是,如果执行此操作:

eval("(function() { console.log(JSON.parse('" + JSON.stringify('THIS IS "NOT" COOL') + "')); })()");

它会失败,而不是打印THIS IS "NOT" COOL

有人可以解释为什么会这样吗?


请注意:

JSON.stringify('THIS IS "NOT" COOL')的结果是字符串"THIS IS \"NOT\" COOL"

如果您尝试执行JSON.parse("THIS IS \"NOT\" COOL"),它将失败,这是因为JS解析器会将字符串"THIS IS \"NOT\" COOL"解释为"THIS IS "NOT" COOL"

如果您执行JSON.parse(JSON.stringify('THIS IS "NOT" COOL')),它将会有效,因为字符串"THIS IS \"NOT\" COOL"会直接传递给JSON.parse

为什么它适用于这种情况,但它不适用于前一种情况?

我唯一的结论是eval在执行代码之前明确地取消了传递给它的所有内容,但我想知道这肯定并且理解为什么eval被设计为像这样工作。

1 个答案:

答案 0 :(得分:2)

这里的问题是角色逃避。查看字符串连接的结果:

"(function() { console.log(JSON.parse('"THIS IS \"NOT\" COOL"')); })()"

请注意,这是实际输出,不是字符串文字。 \这里是一个文字字符,而不是转义字符(我只包括外部引号来表示我正在谈论一个字符串)。

使用eval,字符串将被评估为此代码:

(function() { 
    console.log(JSON.parse('"THIS IS \"NOT\" COOL"')); 
})()

此时,\"实际上被解释为字符转义序列,即字符串 literal '"THIS IS \"NOT\" COOL"'为:< / p>

"THIS IS "NOT" COOL"

这是一个无效的JSON编码字符串。

因此你得到错误

  

SyntaxError: Unexpected token N


eval对你传递的字符串没有任何作用,它被解释为它获取它的方式。