繁体   English   中英

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

[英]How to execute “eval” without writing “eval” in JavaScript

事情是这样的,我们有一个很大的 JS 库要压缩,但是如果YUI 压缩器找到“eval”语句,则不会完全压缩代码,因为担心它会破坏其他东西。 这很好,但我们确切地知道正在评估什么,所以我们不希望它变得保守,因为在 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

有任何想法吗? 谢谢

不确定我是否理解您,但您可以将函数应用于特定的本地(此)范围:

var x = 5;

var f = new Function('alert(this.x)');

function A(x){
    this.x = x;
    f.apply(this,[]);
}

a = new A(10);

当 f 与 A.this 一起应用时,这会发出警报 10

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

但基于 Dimitar 的回答和一些摆弄,这就是我发现的。 似乎 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
  }
});

但是,如果我存储“顶级”本地范围(所有代码,包括 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.
  }
});

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

是否可以重构对某些不属于被压缩文件的外部填充函数的 eval 调用?

我错过了什么吗?

var noteval = this.eval; // can be defined before the file is loaded
noteval("alert('not eval. at all');");

(function() {
    console.log(this);
    noteval("alert('chavs!');");
}).bind(window)();

(function() {
    console.log(this);
    noteval("alert('crappy parents');");
}).bind(window.parent)();

检查http://www.jsfiddle.net/nGL79/将帧作为不同的评估范围。

并且特定于 mootools:

window["ev"+"al"].pass("alert('what');")();
this["ev"+"al"].pass("alert('no!');")(); // local scope too?

var noteval = window["ev"+"al"].create({
    bind: this
}); 

希望其中的一些帮助...希望你不会得到函数 eval 必须被直接调用,而不是通过另一个名称的函数

var e = "e";
window[e+"val"](stuff);

如果可能,您可能想尝试其他压缩库之一,因为 YUI 不再是镇上唯一的游戏。

这里有几篇关于其他可用压缩工具的文章。

无论如何,微软和谷歌似乎比 YUI 做得更好。

这种方式需要jQuery。

function NotEval(code, callBack) {
    $.ajax({
        url: 'data:application/javascript;charset=utf-8,' + encodeURIComponent(code),
        cache:true,
        success: function (r) {
            if (typeof callBack === "function") {
                callBack()
            }
        },
        error: function (r) {
            console.log("Eval error");
            console.log(r)
        }
    })
}

暂无
暂无

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

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