我看到了这种执行代码的方式:
[eval][0]('alert("hello")')
我想知道用方括号括起来的未引用的“eval”是什么意思以及为什么会这样。(例如,window['eval'][0]('alert("hello")')
会导致 TypeError)。有没有描述这种语法的教程?
我看到了这种执行代码的方式:
[eval][0]('alert("hello")')
我想知道用方括号括起来的未引用的“eval”是什么意思以及为什么会这样。(例如,window['eval'][0]('alert("hello")')
会导致 TypeError)。有没有描述这种语法的教程?
这是一个间接的 eval 调用
引用文章:
根据 ES5,所有这些都是间接调用,应该在全局范围内执行代码。
因此,您可以使用这些“技巧”eval
在全局范围内执行,而不是在当前范围内执行。
它之前的工作[eval]
是一个数组,其中它的第 0 个元素是eval
函数,即[eval][0] === eval
,并且您正在调用它并将字符串'alert("hello")'
作为参数传递。
用括号eval
括起来的是一个数组,其中一个元素是eval
.
[eval][0]('alert("hello")')
表示获取数组的第一个元素[eval]
并传递'alert("hello")'
给它。换句话说,
eval('alert("hello")')
window['eval'][0]('alert("hello")')
另一方面,尝试获取window['eval']
不是数组的第一个元素,因此是 TypeError。window['eval']
与eval
除非在范围内有另一个变量称为eval
.
您的示例导致 TypeError 的原因:
window['eval'][0]('alert("hello")')
是因为您遗漏了一组可以使其等效的括号:
[window['eval']][0]('alert("hello")')
您给出的初始语法构造了一个具有一个元素的数组,即函数 eval。因此,该数组的第 0 个元素是 eval 函数,它使用方括号立即取消引用。
在 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 行为的详细信息)。