Javascript 谷歌闭包编译器&x27;s高级_优化选项

Javascript 谷歌闭包编译器&x27;s高级_优化选项,javascript,google-closure-compiler,Javascript,Google Closure Compiler,我最近一直在查看Google闭包编译器。我下载了.jar文件并对其进行了测试。到目前为止,我必须说我印象深刻。我当然可以看到它的有用性,超越了最小化。谷歌团队的道具 不过我确实有一个小小的抱怨。在我看来,就优化而言,您只有两种选择。它要么是简单的优化,要么是高级的优化。前者虽然足够,但非常简单。首先,除非我遗漏了什么,否则它会保留所有属性名不变。它也不会删除无法访问的代码。另一方面,后一种选择的破坏性太大 现在,我对JavaScript相当陌生,所以很可能我遗漏了一些东西。如果我说了些愚蠢的话,

我最近一直在查看Google闭包编译器。我下载了.jar文件并对其进行了测试。到目前为止,我必须说我印象深刻。我当然可以看到它的有用性,超越了最小化。谷歌团队的道具

不过我确实有一个小小的抱怨。在我看来,就优化而言,您只有两种选择。它要么是简单的优化,要么是高级的优化。前者虽然足够,但非常简单。首先,除非我遗漏了什么,否则它会保留所有属性名不变。它也不会删除无法访问的代码。另一方面,后一种选择的破坏性太大

现在,我对JavaScript相当陌生,所以很可能我遗漏了一些东西。如果我说了些愚蠢的话,请随意教我。也就是说,我可以理解JavaScript中重命名的问题。谷歌团队建议使用括号符号(object['property'])而不是点符号(object.property)来访问您不希望更改的属性,并且永远不要混合使用这两种用法。他们还建议使用以下模式“导出”方法:

MyClass = function(name) {
  this.myName = name;
};

MyClass.prototype.myMethod = function() {
  alert(this.myName);
};

window['MyClass'] = MyClass; // <-- Constructor
MyClass.prototype['myMethod'] = MyClass.prototype.myMethod;
MyClass=函数(名称){
this.myName=name;
};
MyClass.prototype.myMethod=函数(){
警报(this.myName);
};

窗口['MyClass']=MyClass;// 这个答案被完全重写了,结果发现有一种方法可以满足用户1127813的需求

您需要提供一个属性映射文件,使用
--property\u map\u input\u file
标志将一些名称映射到它们自己。假设您在
test.js
中有以下原始代码:

/** @constructor */
function Fighter() {
    this.ID        = 42;
    this.fullName  = 'Generic Jen';
    this.hitPoints = 100;
}
Fighter.publishedProperties = ['fullName', 'hitPoints'];

var jen = new Fighter();
var bob = new Fighter();

bob.ID = 54;
bob.fullName = 'Bob the Destructor';
bob.hitPoints = 1337;

for(i = 0; i < Fighter.publishedProperties.length; i++) {
    prop = Fighter.publishedProperties[i];
    alert(prop + ' = ' + bob[prop]);
}
var a=["fullName","hitPoints"],b=new function(){};b.ID=54;b.fullName="Bob the Destructor";b.hitPoints=1337;for(i=0;i<a.length;i++)prop=a[i],alert(prop+" = "+b[prop]);
您将获得一个新文件
test2.js
(包含无效内容)和另一个文件
testprop.txt
,其中包含:

ID:a
hitPoints:c
fullName:b
更改
testprop.txt
,使其看起来像这样:

ID:ID
hitPoints:hitPoints
fullName:fullName
然后以
testprop.txt
作为输入而不是输出重新编译:

java -jar closure-compiler.jar --compilation_level ADVANCED_OPTIMIZATIONS --js test.js --property_map_input_file testprop.txt --js_output_file test2.js
观察
test2.js的内容

/** @constructor */
function Fighter() {
    this.ID        = 42;
    this.fullName  = 'Generic Jen';
    this.hitPoints = 100;
}
Fighter.publishedProperties = ['fullName', 'hitPoints'];

var jen = new Fighter();
var bob = new Fighter();

bob.ID = 54;
bob.fullName = 'Bob the Destructor';
bob.hitPoints = 1337;

for(i = 0; i < Fighter.publishedProperties.length; i++) {
    prop = Fighter.publishedProperties[i];
    alert(prop + ' = ' + bob[prop]);
}
var a=["fullName","hitPoints"],b=new function(){};b.ID=54;b.fullName="Bob the Destructor";b.hitPoints=1337;for(i=0;i<a.length;i++)prop=a[i],alert(prop+" = "+b[prop]);

var a=[“fullName”,“hitPoints”],b=newfunction(){};b、 ID=54;b、 fullName=“Bob the Destructor”;b、 生命值=1337;对于(i=0;i编译器对此有支持,但这很麻烦,并且依赖于名为“goog.reflect.object”的闭包库中的“primitive”:

这就避免了使用带引号的属性。如果这是从闭包库中使用的唯一内容,那么除了“goog.object.transpose”函数之外的所有内容都将被编译出来(goog.object.transpose不是特别的,因此您可以自由地使用替代实现)。这是类型安全的,可用于编译器基于类型的优化(请参见此处的说明:)

关键是必须直接使用goog.reflect.object,使用构造函数和对象文本以及需要保留的属性键

您需要注意的另一点是,在高级模式下,如果在全局范围中定义了Fighter.publishedProperties,则由于命名空间崩溃,它将从构造函数中删除。
@nocollapse
可防止此情况发生。另一种方法是使用助手方法添加属性:

function addPublishedProperties(obj, value) {
  obj.publishedProperties = goog.object.transpose(value);
}

好的,我已经在这里介绍了很多内容,如果您想澄清,请务必告诉我。

首先,谢谢您。但是,您不认为简单地指示编译器的重命名模块留下一个小的标识符列表比在整个程序中使用括号表示法更可取吗(全部40K行)?此外,当/如果您决定使用另一个最小值时会发生什么情况?您被困在括号内的字符串中。这是一种更改不应该更改的内容(程序代码)以产生副作用的情况(即编译器不使用某些变量).至于使用属性映射,恐怕不可行,因为在上面的示例中,XML文件将由应用程序的用户提供(我想我没有明确说明)。关于函数,您是对的。它们当然应该是对象的方法(由readFromXMLNode()中的bindContext变量表示)。我同意最好有避免重命名的语法,但这不是实现您愿望的合适论坛。您可以将建议发送给Google Closure团队,并投票支持您已在提交的特定建议。当编译器尝试在属性输入映射中尊重名称时,不需要这样做.Externs、quoted properties和goog.reflect是更合适的解决方案。我有一个类似问题的答案:
/** @nocollapse */
Fighter.publishedProperties = goog.object.transpose(goog.reflect.object(
    Fighter, {fullName:1, hitPoints:2}));
function addPublishedProperties(obj, value) {
  obj.publishedProperties = goog.object.transpose(value);
}