如何在javascript中覆盖eval函数?

ko1*_*1ik 9 javascript overriding eval

例如:

(function() {
      var proxied = window.eval;
      window.eval = function() {
        return proxied.apply(this, arguments);
      };
    })();
Run Code Online (Sandbox Code Playgroud)

但是这段代码不起作用.

bob*_*nce 12

eval太神奇了.与"真实"函数不同,它可以在调用者中读取和写入局部变量:

function foo() {
    var a= 1;
    eval('a+= 1');
    alert(a); // 2
}
Run Code Online (Sandbox Code Playgroud)

eval代理函数替换它并且你遇到了一个问题:a+= 1proxied函数范围内执行而不是foo.取决于可能导致值丢失的损坏代码中发生的情况,代理的本地,偶然全局变量等的损坏.

因此,eval用完全工作的代理替换它是不可能的.(对于不需要当地人的简单案例,你可以侥幸逃脱.)


T.J*_*der 10

你不能.(这种做法有限,但它非常有限,并没有保持鲍勃所说的魔力.)

eval在至少一个主要的实现(IE的JScript,至少不是通过IE7;没有测试过新的IE8版本)中,它不是一个真正的JavaScript函数,所以马上你会遇到麻烦,因为你赢了无法调用原始通道apply(不是真正重要的通道eval).

最近的ECMAScript 5规范特别禁止eval在严格模式下覆盖(不是你在那里使用严格模式),这让我怀疑有没有超越它的非常好的理由.

  • 严格模式不允许别名/覆盖"eval",因为解释器永远无法预先知道函数块不包含"eval"的隐藏用法.如果一个terp(尤其是JIT)可以确定一个函数只包含简单的代码而没有一个版本,那么它可以对生成的代码执行更广泛的优化. (3认同)

ELL*_*BLE 6

尽管这种方法不是可移植的,但它在某些地方无法使用(因为它满足了ES5的A要求)在MemberExpression中而不是在Value和B中作为引用进行检索,因此它产生了“标准内置函数” 。” - ES5#15.1.2)

(function() {
  var proxied = window.eval
  with({get eval(){ console.log('eval called'); return proxied }}) {
    /* client code */
  }
})()
Run Code Online (Sandbox Code Playgroud)

显然,这仅适用于可以将客户代码包装在with()语句中的情况。尽管在很多情况下,这并不难。显然,相同的方法可以将window具有其所有属性的另一个对象以及getter代理的对象阴影化eval

不支持SpiderMonkey get声明的环境可以使用ES5的声明defineProperty。自己看看。

  • @stackjohn上的@johnjohn,您可以编辑其他人的答案以提出更改建议。仅供将来参考。但是,谢谢!固定。(= (2认同)