Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/412.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_Google Closure Compiler - Fatal编程技术网

Javascript 闭包编译器选择优化?

Javascript 闭包编译器选择优化?,javascript,google-closure-compiler,Javascript,Google Closure Compiler,我正在使用Google的闭包编译器优化(简单优化)来减少一些JS脚本文件的大小。虽然这样做很好,但我在一些函数中遇到了eval语句的问题,编译器替换局部变量会造成严重破坏。我可以尝试重新编写有问题的函数,以击败编译器,但这可能是痛苦的,而且从长远来看是危险的,因为我今天使用的技巧明天可能不会奏效 如果我可以简单地标记我希望编译器保持不变的代码位,那就更好了。目前,我正在考虑使用evals的所有函数,将它们放在一个单独的文件中,并在编译器输出的末尾标记该文件。然而,在我这么做之前,我认为这里值得一

我正在使用Google的闭包编译器优化(简单优化)来减少一些JS脚本文件的大小。虽然这样做很好,但我在一些函数中遇到了eval语句的问题,编译器替换局部变量会造成严重破坏。我可以尝试重新编写有问题的函数,以击败编译器,但这可能是痛苦的,而且从长远来看是危险的,因为我今天使用的技巧明天可能不会奏效

如果我可以简单地标记我希望编译器保持不变的代码位,那就更好了。目前,我正在考虑使用evals的所有函数,将它们放在一个单独的文件中,并在编译器输出的末尾标记该文件。然而,在我这么做之前,我认为这里值得一问——有没有一种方法可以告诉编译器跳过对某些函数的优化。e、 g

//  @compilation_level SIMPLE_OPTIMIZATIONS
function test(one,two)
{

}

function testTwo(alpha,beta)
{

}

// @Closure:Skip

function evalFunc(one,two)
{
 //eval code here
}

//@Closure:EndSkip
最终结果-Skip、EndSkip段之间的代码在没有任何更改的情况下通过编译器


我已经查看了文档,但没有找到任何可以解决此问题的方法。

中有一些关于此问题的提示。由于编译eval通常失败的原因,提议的跳过特性在大多数情况下可能无法解决任何问题

但是,如果您没有访问
evalFunc
范围之外的任何变量,您可以尝试使用括号表示法将所有局部变量重构为属性,并将所有属性名称都放在引号中,以使它们保持一致

比如说,

function evalFunc(one) {
    this['foo'] = one;
    eval('alert(foo);');
}
evalFunc.call({}, 1);
将大致编译为

function(a) {
    this.foo = a; 
    eval("alert(foo);");
};
a.call({}, 1);

保持评估工作正常。它可以在简单模式和高级模式下工作。

谢谢你,@kapep。正如我经常想的(当我没有大声想出来的时候),这是一个多么棒的小论坛啊!为了其他任何想做类似事情的人的利益——我需要处理的最初问题是

function evalFunc(leNom)
{
 var str,obj = {'age':18};
 obj.name = leNom;
 str = 'var out = obj.name + " is " + obj.age + " years old"';
 eval(str);
 alert(out);
}
通过Closure的简单优化,您可以得到

  function evalFunc(a){eval('var out = obj.name + " is " + obj.age + " years old"');
  alert(out)};
它平躺在它的脸上

将此更改为

function evalFunc(leNom)
{
 var str;
 this['obj'] = {'age':18};
 this['obj'].name = leNom;
 str = 'var out = obj.name + " is " + obj.age + " years old"';
 eval(str);
 alert(out);
}
而收尾又带来了什么

function evalFunc(a){this.obj={age:18};this.obj.name=a;
eval('var out = obj.name + " is " + 
obj.age + " years old"');alert(out)};
这很好用

*------------------
测试后的脚注。如果像我一样,您无法避免JS中的evals,并且希望压缩或以其他方式混淆代码,请注意前面的道路充满了陷阱。一个粗心的编辑是所有需要打破你的代码。微软的ajaxminifier提供了对包含evals的代码的更多控制,因此它可能是一个更好的解决方案。然而,到目前为止,最安全的做法是简单地取出所有包含eval的函数,将它们放在一个单独的文件中,并将其标记到压缩输出中。在任何编写良好的代码中,使用evals的函数应该相对较少。gzip压缩确保了良好的带宽利用率,同时避免了压缩后出错的恶意评估的噩梦。

如果代码不太复杂,可以使用函数构造函数:


新函数(“a”、“b”返回值('a+b'))

鉴于编译器根本不涉及字符串,也许您可以通过从字符串创建整个函数来利用这一点。对于您的示例,编译器应该抱怨使用
this
关键字有危险。最好使用
窗口
或对对象显式显示。这种解决方案似乎是一个非常糟糕的主意。基本上,您正在将所有值放入全局范围,并可能覆盖全局值。您是对的,我添加了一些显式函数上下文。可能的副本供参考:我也在github上问了这个问题: