如何在JavaScript中不写"eval"的情况下执行"eval"

ada*_*Lev 7 javascript mootools json eval yui-compressor

这是交易,我们有一个我们想要压缩的大型JS库,但如果它找到一个"eval"语句,YUI压缩器不能完全压缩代码,因为担心它会破坏别的东西.这很好,但是我们确切地知道什么是eval'd,所以我们不希望它变得保守,因为在MooTools JSON.decode中有一个eval语句

所以基本上问题是,是否有任何替代(可能是创造性的)方法来编写一个返回eval函数的表达式?我试了几个,但没有骰子:

window['eval'](stuff);
window['e'+'val'](stuff);
// stuff runs in the global scope, we need local scope

this['eval'](stuff);
// this.eval is not a function

(new Function( "with(this) { return " + '(' + stuff + ')' + "}"))() 
// global scope again
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?谢谢

ada*_*Lev 4

感谢所有的想法,我最终只是在输出 JS 的构建脚本中进行文本替换,基本上在所有内容都被压缩后用 eval 替换 $EVAL$ 。我希望有一种纯粹的 JS 方式,但是有这么多不同的 eval 浏览器实现,最好不要管 eval

但根据迪米塔的回答和一些摆弄,这就是我发现的。似乎 this['eval'] 不起作用的原因是因为它发生的地方,在 MooTools JSON.decode 中,也是哈希内部:

var JSON = new Hash({
  // snip snip
  decode: function(string, secure) {
    if ($type(string) != 'string' || !string.length) return null;
    if (secure && !(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''))) return null;

    return this.eval('(' + string + ')'); // Firefox says: TypeError: this.eval is not a function
  }
});
Run Code Online (Sandbox Code Playgroud)

但是,如果我存储“顶级”本地作用域(所有代码,包括 mootools,都在匿名函数内运行),那么它可以工作:

var TOP = this;
var JSON = new Hash({
  // snip snip
  decode: function(string, secure) {
    if ($type(string) != 'string' || !string.length) return null;
    if (secure && !(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''))) return null;

    return TOP.eval('(' + string + ')'); // All good, things run within the desired scope.
  }
});
Run Code Online (Sandbox Code Playgroud)

然而这在 Safari 中不起作用,所以底线是,我试图做的事情不能交叉兼容。eval 是一个特殊的敏感函数,每个浏览器都会以不同的方式对待它。