[英]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.