Javascript 谷歌闭包编译器&x27;s高级优化isn';t优化某些变量
我遇到了一个关于Google Closure Javascript编译器和高级优化的问题。如文档所示,为了保留导出的Javascript,我执行以下操作:Javascript 谷歌闭包编译器&x27;s高级优化isn';t优化某些变量,javascript,google-closure-compiler,Javascript,Google Closure Compiler,我遇到了一个关于Google Closure Javascript编译器和高级优化的问题。如文档所示,为了保留导出的Javascript,我执行以下操作: var myClass = function() { this["myFunc"] = this.myFunc; this["myFunc2"] = this.myFunc2; }; window["myClass"] = myClass; myClass.prototype = { myFunc: function()
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")
}};
但我仍然不知道是什么原因造成的。原因是,通过高级优化,GCC对待myObject[“a”]的方式与对待myObject.a的方式不同。请尝试以下操作:
var myObject = {};
myObject.attr1 = 3;
myObject["attr2"] = 4;
window["myObject"] = myObject;
// ==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"); }
};
它将通过高级优化编译为:
window.myObject={a:3,attr2:4};
我想你会看到你现在需要做什么。原因是,通过高级优化,GCC对待myObject[“a”]的方式与对待myObject.a的方式不同。请尝试以下操作:
var myObject = {};
myObject.attr1 = 3;
myObject["attr2"] = 4;
window["myObject"] = myObject;
// ==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"); }
};
它将通过高级优化编译为:
window.myObject={a:3,attr2:4};
我想您将看到现在需要做什么。从中,您似乎需要显式地将原型方法导出到构造函数之外:
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;
这看起来像广告宣传的那样有效,尽管对我来说这似乎是一个奇怪的优化(所有重复的“原型”引用都添加了大量字节):
从中可以看出,您需要在构造函数之外显式导出原型方法:
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;
这看起来像广告宣传的那样有效,尽管对我来说这似乎是一个奇怪的优化(所有重复的“原型”引用都添加了大量字节):
我不能重复你的问题。如果我转到并编译以下内容:
var myObject = {};
myObject.attr1 = 3;
myObject["attr2"] = 4;
window["myObject"] = myObject;
// ==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")}};
属性将按预期重命名
至于第二个示例,它与闭包编译器概念有关,称为。extern是一个符号,它将在JavaScript运行的环境中预定义,例如在Web编程的情况下window
或document
。因为这些名称在环境中是固定的,所以编译器不能损坏这些名称
如果查看中的DEFAULT\u EXTERNS\u NAMES
列表,您将看到文件夹中的文件列表。这些文件的内容定义了编译器知道的外部程序(您也可以添加自己的外部程序)。webgl.js
和w3c_indexeddb.js
都使用名为get
(分别为WebGLContextAttributes
和IDBObjectStore
)的属性定义类型。默认情况下,编译器不知道myClass
中的this
的类型,据它所知,this
可能引用WebGLContextAttributes
或IDBObjectStore
的实例,在这种情况下,重命名get
是不安全的
通过使用类型注释(如
@constructor
)和编译器选项(如歧义属性
和消歧属性
)的组合,编译器可以确定此
将始终引用myClass
的新实例,并一致地将其所有引用重命名为get
。您可以在《闭包:最终指南》第14章中阅读有关这些编译器优化的更多信息。我不能重复您的问题。如果我转到并编译以下内容:
var myObject = {};
myObject.attr1 = 3;
myObject["attr2"] = 4;
window["myObject"] = myObject;
// ==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")}};
属性将按预期重命名
至于第二个示例,它与闭包编译器概念有关,称为。extern是一个符号,它将在JavaScript运行的环境中预定义,例如在Web编程的情况下window
或document
。因为这些名称在环境中是固定的,所以编译器不能损坏这些名称
如果查看中的DEFAULT\u EXTERNS\u NAMES
列表,您将看到文件夹中的文件列表。这些文件的内容定义了编译器知道的外部程序(您也可以添加自己的外部程序)。webgl.js
和w3c_indexeddb.js
都使用名为get
(分别为WebGLContextAttributes
和IDBObjectStore
)的属性定义类型。默认情况下,编译器不知道myClass
中的this
的类型,据它所知,this
可能引用WebGLContextAttributes
或IDBObjectStore
的实例,在这种情况下,重命名get
是不安全的
通过使用类型注释(如
@constructor
)和编译器选项(如歧义属性
和消歧属性
)的组合,编译器可以确定此
将始终引用myClass
的新实例,并一致地将其所有引用重命名为get
。您可以在《闭包:最终指南》第14章中阅读有关这些编译器优化的更多信息。不。我理解这一点,这就是为什么我要做this[“xyz”]=this.xyz
。这类似于窗口[“myObject”]=myObject
,除非我遗漏了什么。否。我理解这一点,这就是为什么我要做this[“xyz”]=this.xyz
。这类似于窗口[“myObject”]=myObject
,除非我遗漏了什么。我应该特别使用哪些注释?如何通过命令行界面设置歧义/消歧?您需要使用包含类型信息的注释:@constructor、@extends、@param、,和@return。很遗憾,您无法从命令行界面设置歧义/消除歧义。您可以选择(1)使用plovr(我推荐,但我有偏见!),或者(2)以编程方式使用编译器并编写代码