google 闭包编译器的高级优化并未优化某些变量
我遇到了带有高级优化的 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;
这显然不太理想。
我怎样才能防止这种情况发生?
进一步的实验表明,某些关键字(例如“get”)不会被编译。
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")
}};
我仍然不知道是什么原因造成的。
I'm running into an issue with the Google Closure Javascript compiler with advanced optimization. As the documentation suggests, to preserve exported Javascript I do something like this:
var myClass = function() {
this["myFunc"] = this.myFunc;
this["myFunc2"] = this.myFunc2;
};
window["myClass"] = myClass;
myClass.prototype = {
myFunc: function() { alert("myFunc"); },
myFunc2: function() { alert("myFunc2"); }
};
The issue is that sometimes, for whatever reason, myFunc
and myFunc2
don't get shortened, and I see code like this in the final output:
x.myFunc=x.myFunc;x.myFunc2=x.myFunc2;
This is obviously less than ideal.
How can I prevent this from happening?
Further experimentation has shown that there are certain keywords, e.g. 'get' that don't get compiled.
var myClass = function() {
this["get"] = this.get;
this["myFunc2"] = this.myFunc2;
};
window["myClass"] = myClass;
myClass.prototype = {
get: function() { alert("myFunc"); },
myFunc2: function() { alert("myFunc2"); }
};
Compiles into
function a() {
this.get = this.get;
this.myFunc2 = this.a
}
window.myClass = a;
a.prototype = {get:function() {
alert("myFunc")
}, a:function() {
alert("myFunc2")
}};
I still don't know what's causing it though.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我无法重复你的问题。如果我转到 http://closure-compiler.appspot.com/home 并编译以下内容:
然后我得到以下结果:
属性被重命名,如预期的那样。
至于你的第二个例子,它与称为
如果您查看 CommandLineRunner.java,您将看到 externs 文件夹。这些文件的内容定义了编译器知道的外部(您也可以添加自己的外部)。
webgl.js
和w3c_indexeddb.js
都使用名为get
的属性定义类型(WebGLContextAttributes
和IDBObjectStore分别)。默认情况下,编译器不知道
myClass
中this
的类型,因此就其所知,this
可以引用以下实例:WebGLContextAttributes
或IDBObjectStore
,在这种情况下,重命名get
是不安全的。通过使用类型注释(例如
@constructor
)和编译器选项(例如ambiguateProperties
和disambiguateProperties
)的组合,编译器可以确定this
将始终引用myClass
的新实例,并将其所有引用一致重命名为get
。您可以在Closure:权威指南的第14章中阅读有关这些编译器优化的更多信息。I cannot duplicate your problem. If I go to http://closure-compiler.appspot.com/home and compile the following:
Then I get the following result:
The properties are renamed, as expected.
As for your second example, it has to do with a Closure Compiler concept known as externs. An extern is a symbol that will be predefined in the environment in which the JavaScript will run, such as
window
ordocument
in the case of Web programming. Because such names are fixed in the environment, the Compiler cannot mangle these names.If you look at the
DEFAULT_EXTERNS_NAMES
list in CommandLineRunner.java, you will see a list of files from the externs folder. The contents of these files define the externs that the Compiler knows about (you can also add your own externs). Bothwebgl.js
andw3c_indexeddb.js
define types with a property namedget
(WebGLContextAttributes
andIDBObjectStore
, respectively). By default, the Compiler does not know the type ofthis
inmyClass
, so as far as it knows,this
could refer to an instance of eitherWebGLContextAttributes
orIDBObjectStore
, in which case it would not be safe to renameget
.By using a combination of type annotations (such as
@constructor
) and Compiler options such asambiguateProperties
anddisambiguateProperties
, the Compiler can determine thatthis
will always refer to a new instance ofmyClass
and rename all of its references toget
consistently. You can read more about these Compiler optimizations in Chapter 14 of Closure: The Definitive Guide.从此处的示例来看,您似乎需要在构造函数之外显式导出原型方法:
这似乎像宣传的那样工作,尽管对我来说这似乎是一个奇怪的优化(所有重复的“原型”引用都会添加很多字节):
From the example here, it looks like you need to explicitly export prototype methods outside of the constructor:
This seems to work as advertised, though it seems like an odd optimization to me (all the repeated "prototype" references add a lot of bytes):
原因是,通过 ADVANCED_OPTIMIZATIONS,GCC 对待 myObject["a"] 的方式与 myObject.a 不同。尝试以下操作:
它将编译为此,并使用 ADVANCED_OPTIMIZATIONS:
我想您会看到现在需要做什么。
The reason is that, with ADVANCED_OPTIMIZATIONS, the GCC treats myObject["a"] differently from myObject.a. Try the following:
It will compile to this, with ADVANCED_OPTIMIZATIONS:
I think you'll see what you need to do now.