我遇到了使用高级优化的Google Closure Javascript编译器的问题。正如文档所示,为了保留导出的Javascript,我做了类似这样的事情:
var myClass = function() {
this["myFunc"] = this.myFunc;
this["myFunc2"] = this.myFunc2;
};
window["myClass"] = myClass;
myClass.prototype = {
myFunc: function() { alert("myFunc"); },
myFunc2: function() { alert("myFunc2"); }
};
问题在于,无论出于何种原因,有时myFunc
和myFunc2
都不会缩短,我在最终输出中看到这样的代码:
x.myFunc=x.myFunc;x.myFunc2=x.myFunc2;
这显然不太理想。
如何防止这种情况发生?
进一步的实验表明,某些关键字,例如“得到”没有被编译。
var myClass = function() {
this["get"] = this.get;
this["myFunc2"] = this.myFunc2;
};
window["myClass"] = myClass;
myClass.prototype = {
get: function() { alert("myFunc"); },
myFunc2: function() { alert("myFunc2"); }
};
编译成
function a() {
this.get = this.get;
this.myFunc2 = this.a
}
window.myClass = a;
a.prototype = {get:function() {
alert("myFunc")
}, a:function() {
alert("myFunc2")
}};
我仍然不知道是什么导致了它。
答案 0 :(得分:4)
我不能复制你的问题。如果我转到http://closure-compiler.appspot.com/home并编译以下内容:
// ==ClosureCompiler==
// @compilation_level ADVANCED_OPTIMIZATIONS
// @output_file_name default.js
// ==/ClosureCompiler==
var myClass = function() {
this["myFunc"] = this.myFunc;
this["myFunc2"] = this.myFunc2;
};
window["myClass"] = myClass;
myClass.prototype = {
myFunc: function() { alert("myFunc"); },
myFunc2: function() { alert("myFunc2"); }
};
然后我得到以下结果:
function a(){this.myFunc=this.a;this.myFunc2=this.b}window.myClass=a;a.prototype={a:function(){alert("myFunc")},b:function(){alert("myFunc2")}};
按预期重命名属性。
至于你的第二个例子,它与名为externs的Closure Compiler概念有关。 extern 是将在运行JavaScript的环境中预定义的符号,例如在Web编程的情况下为window
或document
。因为这些名称在环境中是固定的,所以编译器不能破坏这些名称。
如果查看CommandLineRunner.java中的DEFAULT_EXTERNS_NAMES
列表,您会看到externs文件夹中的文件列表。这些文件的内容定义了编译器知道的外部实例(您也可以添加自己的外部实例)。 webgl.js
和w3c_indexeddb.js
都定义了具有名为get
(WebGLContextAttributes
和IDBObjectStore
的属性的类型。默认情况下,编译器不知道this
中myClass
的类型,因此就其所知,this
可以引用WebGLContextAttributes
或{{的实例1}},在这种情况下,重命名IDBObjectStore
是不安全的。
通过使用类型注释(例如get
)和编译器选项(例如@constructor
和ambiguateProperties
)的组合,编译器可以确定disambiguateProperties
将始终引用this
的新实例,并始终将其对myClass
的所有引用重命名。您可以在 Closure:The Definitive Guide 的第14章中阅读有关这些编译器优化的更多信息。
答案 1 :(得分:1)
从example here开始,您需要在构造函数之外显式导出原型方法:
var myClass = function() {};
myClass.prototype = {
myFunc: function() { alert("myFunc"); },
myFunc2: function() { alert("myFunc2"); }
};
window["myClass"] = myClass;
myClass.prototype["myFunc"] = myClass.prototype.myFunc;
myClass.prototype["myFunc2"] = myClass.prototype.myFunc2;
这似乎与宣传的一样,虽然对我来说似乎是一个奇怪的优化(所有重复的“原型”引用都添加了很多字节):
function a(){}a.prototype={a:function(){alert("myFunc")},
b:function(){alert("myFunc2")}};
window.myClass=a;
a.prototype.myFunc=a.prototype.a;
a.prototype.myFunc2=a.prototype.b;
答案 2 :(得分:0)
原因在于,使用ADVANCED_OPTIMIZATIONS,GCC将myObject [“a”]与myObject.a区别对待。请尝试以下方法:
var myObject = {};
myObject.attr1 = 3;
myObject["attr2"] = 4;
window["myObject"] = myObject;
它将使用ADVANCED_OPTIMIZATIONS编译到此:
window.myObject={a:3,attr2:4};
我想你会看到你现在需要做什么。