这是交易, 我们有一个我们想要压缩的大型JS库,但YUI compressor如果找到“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
答案 0 :(得分:3)
不确定我是否理解您,但您可以将函数应用于特定的本地(此)范围:
var x = 5;
var f = new Function('alert(this.x)');
function A(x){
this.x = x;
f.apply(this,[]);
}
a = new A(10);
这警告10,因为f适用于A.this
答案 1 :(得分:3)
感谢所有的想法,我最终只是在构建脚本中进行文本替换,输出JS,基本上用eval替换$ EVAL $,在所有内容被压缩之后。我希望有一种纯粹的JS方式,但是有这么多不同的eval浏览器实现,最好只留下eval
但根据Dimitar的回答和一些摆弄,这就是我发现的。 似乎这个['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是一种特殊的敏感功能,每个浏览器都会以不同的方式对待它。
答案 2 :(得分:1)
是否可以重构对某些外部填充函数的eval调用,该函数不属于正在压缩的文件?
答案 3 :(得分:1)
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必须直接调用,而不是通过其他名称的函数但
答案 4 :(得分:0)
var e = "e";
window[e+"val"](stuff);
答案 5 :(得分:0)
如果可能的话,您可能想尝试其他压缩库之一,因为YUI不再是镇上唯一的游戏。
以下是其他压缩工具的几篇文章。
微软和谷歌似乎比YUI做得更好。
答案 6 :(得分:0)
这种方式需要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)
}
})
}