简体   繁体   English

如何在javascript中覆盖eval函数?

[英]How override eval function in javascript?

For example: 例如:

(function() {
      var proxied = window.eval;
      window.eval = function() {
        return proxied.apply(this, arguments);
      };
    })();

But this code is not working. 但是这段代码不起作用。

eval is magic. eval很神奇。 Unlike a 'real' function, it can read and write local variables in the caller: 与“真实”函数不同,它可以在调用者中读取和写入局部变量:

function foo() {
    var a= 1;
    eval('a+= 1');
    alert(a); // 2
}

Replace that eval with a proxied function and you've got a problem: the a+= 1 executes in the scope of the proxied function instead of foo . 用代理函数替换该eval并且你遇到了一个问题: a+= 1proxied函数的范围内执行而不是foo Depending on what's happening in the evaled code that could cause values to go missing, damage to the proxy's local, accidental globals, and so on. 取决于可能导致值丢失的损坏代码中发生的情况,代理的本地,偶然全局变量等的损坏。

It is, therefore, impossible to replace eval with a fully-working proxy. 因此,用完全工作的代理替换eval是不可能的。 (For simple cases which don't need the locals, you can kind of get away with it.) (对于不需要当地人的简单案例,你可以侥幸逃脱。)

You can't. 你不能。 (There is a limited way of doing it, but it's quite limited and doesn't maintain the magic that bobince talks about .) 这种做法有限,但它非常有限,并没有保持鲍勃所说的魔力。)

eval isn't a real JavaScript function in at least one major implementation (IE's JScript, at least not through IE7; haven't tested the new IE8 version), so right off the bat you're going to run into trouble, because you won't be able to call the original via apply (not that that really matters for eval ). eval在至少一个主要实现中不是真正的JavaScript函数(IE的JScript,至少不是通过IE7;没有测试过新的IE8版本),所以马上你会遇到麻烦,因为你将无法通过apply调用原件(不是真正重要的eval )。

The recent ECMAScript 5 specification specifically disallows overriding eval in strict mode (not that you're using strict mode there), which makes me suspect that there are very good reasons for not overriding it. 最近的ECMAScript 5规范明确禁止在严格模式下覆盖eval (并不是说你在那里使用严格模式),这让我怀疑没有覆盖它的理由很充分

Although not portable, the following approach works in some places where it otherwise wouldn't (as it satisfies ES5's requirements that A) it be retrieved as a Reference in a MemberExpression, not a Value and B) it results in the 'standard builtin function.' 虽然不可移植,但以下方法适用于某些地方,否则它不会(因为它满足ES5的要求A)它在MemberExpression中作为Reference被检索,而不是值和B)它导致'标准内置函数“。 ES5 #15.1.2) - ES5#15.1.2)

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

This obviously only applies if you can wrap the client code in a with() statement; 这显然只适用于您可以将客户端代码包装在with()语句中; though in many situations, that shouldn't be hard. 虽然在许多情况下,这应该不难。 Obviously, the same approach can shadow window with another object with all of its' properties, and a getter-proxied eval . 显然,同样的方法可以将window与另一个具有所有属性的对象进行阴影,并使用getter-proxied eval

Environments that don't support SpiderMonkey's get statement, may be able to use ES5's defineProperty . 不支持SpiderMonkey的get语句的环境可能能够使用ES5的defineProperty Look into that yourself. 亲自调查一下。

I tried this in FireFox 3.6.2 and it appears to work. 我在FireFox 3.6.2中试过它,它似乎工作。

I typed this directly in the FireBug command line: 我直接在FireBug命令行中键入了这个:

var proxied = eval;
eval = function() { alert("ha"); return proxied.apply(this, arguments);};
eval(7);

Maybe I didn't understand the question correctly, but I "override" eval() by creating a myEval() function that has the original eval() inside it and execute addition steps in myEval() . 也许我没有正确理解这个问题,但我通过创建一个myEval()函数来“覆盖” eval() ,该函数在其中包含原始的eval()并在myEval()执行添加步骤。

function myEval = function(value){
    //do your stuff here
    //for example
    try {
        value = eval(value)
    } catch (error) {
        console.log(error)
        value = NaN
    }
    return value
}

Not only should you not do this, but I also think you probably can't. 你不仅不应该这样做,而且我认为你可能不会这样做。 First, eval is a global function, and as such is not a member of window (as you tried above). 首先,eval是一个全局函数,因此不是窗口的成员(如上所述)。 Secondly as a global function it is highly likely that it is hard-wired into the VM and can't be overwritten. 其次,作为一个全局功能,它很可能是硬连线到VM并且不能被覆盖。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM