我看到这种方式执行代码:
[eval][0]('alert("hello")')
我想知道方括号包围的不带引号的'eval'意味着什么,以及为什么这样做。 (例如,window['eval'][0]('alert("hello")')
将导致TypeError)。有没有描述这种语法的教程?
答案 0 :(得分:6)
引用文章:
根据ES5,所有这些都是间接调用,应该执行 全球范围内的代码。
因此,您可以使用这些“技巧”在全局范围内执行eval
而不是当前范围。
它在[eval]
之前是一个数组,其第0个元素是eval
函数,即[eval][0] === eval
,并且您正在调用它传递字符串'alert("hello")'
作为论点。
答案 1 :(得分: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
的变量。
答案 2 :(得分:2)
您的示例导致TypeError的原因:
window['eval'][0]('alert("hello")')
是因为你遗漏了一组括号,它们会使它等价:
[window['eval']][0]('alert("hello")')
您给出的初始语法构造了一个包含一个元素的数组,即函数eval。因此,此数组的第0个元素是eval函数,使用方括号立即取消引用。
答案 3 :(得分: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行为的详细信息。)