Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/447.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何执行;“评估”;不写;“评估”;在JavaScript中_Javascript_Json_Mootools_Eval_Yui Compressor - Fatal编程技术网

如何执行;“评估”;不写;“评估”;在JavaScript中

如何执行;“评估”;不写;“评估”;在JavaScript中,javascript,json,mootools,eval,yui-compressor,Javascript,Json,Mootools,Eval,Yui Compressor,事情是这样的, 我们有一个想要压缩的大JS库,但是如果它发现一个“eval”语句,就不会完全压缩代码,因为担心它会破坏其他东西。 这很好,但我们确切地知道什么是eval'd,所以我们不希望它变得保守,因为MooTools JSON.decode中有eval语句 所以基本上问题是,有没有其他(可能是创造性的)方法来编写返回eval函数的表达式? 我试了几次,但没有掷骰子: window['eval'](stuff); window['e'+'val'](stuff); // stuff runs

事情是这样的, 我们有一个想要压缩的大JS库,但是如果它发现一个“eval”语句,就不会完全压缩代码,因为担心它会破坏其他东西。 这很好,但我们确切地知道什么是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
有什么想法吗?
Thx

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

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


微软和谷歌似乎比YUI做得更好。

可以重构对某些外部填充函数的eval调用,这些函数不是被压缩文件的一部分吗?

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


当f与A一起应用时,这会提醒10。这

我是否遗漏了什么

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)();
用不同的评估范围检查框架

并且特定于mootools:

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


希望这能对你有所帮助。。。希望您不会得到函数eval必须直接调用,而不是通过另一个名称的函数调用。不过

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

但根据迪米特尔的回答和一些胡闹,我发现了以下几点。 似乎这个['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是一个特殊的敏感函数,每个浏览器都会以不同的方式对待它。

这种方式需要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)
        }
    })
}

那不行,事情是在全球范围内运行的。此外,webkit似乎也不可移植,它会发出
window.eval===window['eval']==window['e'+'val']
所以没有骰子。。东西在窗口范围内得到评估,这不是我们需要的。谢谢你的建议。我曾经玩过谷歌闭包,但它对我们来说太激进了,重命名了太多东西,破坏了代码。将需要一些时间来调整代码,使其运行,并且可能会引入新的bug。查看微软的东西会很好,但我们是一家Java/OSX商店Google闭包的诀窍是只使用简单的压缩,如果压缩失败,只使用空白。这是一个安全的选择,只是删除了所有的空白,这总比什么都没有好。这也适用于YUI,它缩小了所有这些,但它不会用较短的变量名替换长的变量名,因为evalsyou会出错,因为
eval
不被认为是一个普通函数。你可能比YUI压缩器更聪明,但你会遇到浏览器,这些浏览器不允许或很快不允许你用任何其他名称调用
eval
。感谢你的想法,至少现在我明白了为什么这个.eval不起作用。看看我自己的答案
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
  }
});
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.
  }
});
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)
        }
    })
}