如何重写javascript中的eval函数?

发布于 2024-08-27 03:21:56 字数 202 浏览 5 评论 0原文

例如:

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

但是这段代码不起作用。

For example:

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

But this code is not working.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

盗梦空间 2024-09-03 03:21:56

eval 很神奇。与“真实”函数不同,它可以在调用者中读取和写入局部变量:

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

eval 替换为代理函数,您就会遇到问题:a+= 1 > 在 proxied 函数而不是 foo 的范围内执行。根据评估代码中发生的情况,可能会导致值丢失、代理本地损坏、意外全局变量等等。

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

eval is magic. 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. 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. (For simple cases which don't need the locals, you can kind of get away with it.)

放我走吧 2024-09-03 03:21:56

你不能。 (有一种有限的方法来做到这一点,但它非常有限,并且不能保持bobince 谈论。)

eval 至少在一个主要实现中不是真正的 JavaScript 函数(IE 的 JScript,至少不是通过 IE7;还没有测试新的 IE8 版本),所以马上你就会遇到麻烦,因为你将无法通过 apply 调用原始版本 (这对于 eval 来说并不重要)。

最近的 ECMAScript 5 规范明确禁止在严格模式下重写 eval(并不是说您在那里使用严格模式),这让我怀疑有非常充分的理由不这样做覆盖它。

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).

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.

嘦怹 2024-09-03 03:21:56

虽然不可移植,但以下方法在某些地方可以工作,否则无法工作(因为它满足 ES5 的要求,A)它作为 MemberExpression 中的引用而不是值进行检索,B)它会产生“标准内置函数” .' — ES5 #15.1.2)

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

这显然仅适用于您可以包装客户端代码的情况在 with() 语句中;尽管在很多情况下,这应该不难。显然,同样的方法可以用另一个对象及其所有属性和 getter 代理的 eval 来隐藏 window

不支持SpiderMonkey的get语句的环境也许能够使用ES5的defineProperty。你自己看看吧。

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 #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; 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.

Environments that don't support SpiderMonkey's get statement, may be able to use ES5's defineProperty. Look into that yourself.

策马西风 2024-09-03 03:21:56

我在 FireFox 3.6.2 中尝试过,它似乎有效。

我直接在 FireBug 命令行中输入:

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

I tried this in FireFox 3.6.2 and it appears to work.

I typed this directly in the FireBug command line:

var proxied = eval;
eval = function() { alert("ha"); return proxied.apply(this, arguments);};
eval(7);
猥︴琐丶欲为 2024-09-03 03:21:56

也许我没有正确理解这个问题,但我通过创建一个具有原始 eval()< 的 myEval() 函数来“覆盖”eval() /code> 并执行 myEval() 中的附加步骤。

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

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().

function myEval = function(value){
    //do your stuff here
    //for example
    try {
        value = eval(value)
    } catch (error) {
        console.log(error)
        value = NaN
    }
    return value
}
一花一树开 2024-09-03 03:21:56

你不仅不应该这样做,而且我认为你可能也不能这样做。首先, eval 是一个全局函数,因此不是 window 的成员(正如您上面尝试的那样)。其次,作为一个全局函数,它很可能被硬连接到虚拟机中并且无法被覆盖。

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). Secondly as a global function it is highly likely that it is hard-wired into the VM and can't be overwritten.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文