【问题标题】:Why does [eval] work in [eval][0]('code')?为什么 [eval] 在 [eval][0]('code') 中有效?
【发布时间】:2013-10-22 06:06:58
【问题描述】:

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

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

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

【问题讨论】:

  • 还要注意[alert][0]('test') 给出了TypeError: Illegal Invocation。这是因为alert 中通常绑定到windowthis 在像这样调用时未绑定(警告。[alert.bind(window)][0]('test') 没有错误。
  • 另外,查看question #4670805 以了解为什么您希望在全局范围内执行eval 的示例。
  • @lyrically wicked:您应该将 Matteo 的答案标记为正确的答案……它是最佳答案。

标签: javascript


【解决方案1】:

那是indirect eval call

引自文章:

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

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

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

【讨论】:

    【解决方案2】:

    您的示例导致 TypeError 的原因:

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

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

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

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

    【讨论】:

    • 您可能想说明为什么会这样做,而不是简单的eval() 调用。
    • 根据perfectionkills.com/global-eval-what-are-the-optionseval("code")是直接的eval调用(在调用者范围内执行),[eval][0]("code")是在全局范围内执行的间接调用。但为什么会发生呢?至于我,我不知道……
    【解决方案3】:

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

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

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

    eval('alert("hello")')


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

    另一方面,试图获取window['eval'] 的第一个元素,它不是一个数组,因此是TypeError。 window['eval']eval 相同,除非范围内有另一个名为 eval 的变量。

    【讨论】:

      【解决方案4】:

      在 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 行为的详细信息)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-15
        • 1970-01-01
        • 2020-03-14
        相关资源
        最近更新 更多