1

我看到了这种执行代码的方式:

[eval][0]('alert("hello")')  

我想知道用方括号括起来的未引用的“eval”是什么意思以及为什么会这样。(例如,window['eval'][0]('alert("hello")')会导致 TypeError)。有没有描述这种语法的教程?

4

4 回答 4

6

这是一个间接的 eval 调用

引用文章:

根据 ES5,所有这些都是间接调用,应该在全局范围内执行代码

因此,您可以使用这些“技巧”eval在全局范围内执行,而不是在当前范围内执行。

它之前的工作[eval]是一个数组,其中它的第 0 个元素是eval函数,即[eval][0] === eval,并且您正在调用它并将字符串'alert("hello")'作为参数传递。

于 2013-10-22T06:23:26.370 回答
2

用括号eval括起来的是一个数组,其中一个元素是eval.

[eval][0]('alert("hello")')

表示获取数组的第一个元素[eval]并传递'alert("hello")'给它。换句话说,

eval('alert("hello")')


window['eval'][0]('alert("hello")')

另一方面,尝试获取window['eval']不是数组的第一个元素,因此是 TypeError。window['eval']eval除非在范围内有另一个变量称为eval.

于 2013-10-22T06:11:02.200 回答
2

您的示例导致 TypeError 的原因:

window['eval'][0]('alert("hello")')

是因为您遗漏了一组可以使其等效的括号:

[window['eval']][0]('alert("hello")')

您给出的初始语法构造了一个具有一个元素的数组,即函数 eval。因此,该数组的第 0 个元素是 eval 函数,它使用方括号立即取消引用。

于 2013-10-22T06:11:11.930 回答
1

在 Javascript 中

[x]

是一个包含 的元素的列表x。因此

[x][0]

只是一种冗长而低效的说法x

你的例子

[eval][0]('alert("hello")')

因此就像

eval('alert("hello")')

这种诡计通常出现在 Javascript 特洛伊木马或病毒中,作者试图掩饰正在发生的事情。

然而,Javascript 充满了特殊情况,当与eval代码一起使用时,也可能具有强制全局评估而不是局部评估的含义。

function defun(s) { [eval][0](s); }
function defun2(s) { eval(s); }

defun2("function square(x){return x*x}")
---> undefined

square(12)
---> ReferenceError: square is not defined

defun("function square(x){return x*x}")
---> undefined

square(12)
---> 144

有关详细信息,请参阅 Matteo Tassinari 答案链接(请注意,链接的文章有点过时,因此请忽略有关 webkit 行为的详细信息)。

于 2013-10-22T06:25:59.163 回答