我是Google封闭编译器的新手,在阅读了闭包工具网站中的文档后,我创建了一个js并进行了测试。
但是我发现即使我使用高级编译级别,编译的代码仍然很容易被分解。
例如,这是代码:
//2
window["_NameSpace_"]={};
window["_NameSpaceInternal_"]={};
(function() {
_NameSpaceInternal_.Class = function() {
var clazz = function() {
this["init"] && this["init"].apply(this, arguments);
};
var pros = {}, arg;
for(var c = 0, k = arguments.length; c < k; ++c) {
arg = arguments[c];
if( typeof arg === 'function') {
if(c == 0 && k > 1) {
var F = function() {
};
F.prototype = arg.prototype;
pros = new F;
arg = arg.prototype;
}
} else {
if(arg.init) {
clazz = arg["init"];
delete arg["init"]
}
}
}
for(var p in arg)
pros[p] = arg[p]
clazz.prototype = pros;
return clazz;
};
})();
(function(d){
d["Person"]=_NameSpaceInternal_.Class({
"init":function(name){
this.name=name;
},
"whatever":function(aaa){
}
});
})(_NameSpace_);
编译完成后(我为人类阅读制作了一个漂亮的格式):
window.__MapNS__ = {};
window.__MapNSImpl__ = {};
__MapNSImpl__.a = function() {
function c() {
this.init && this.init.apply(this, arguments)
}
for (var b = {}, a, d = 0, e = arguments.length; d < e; ++d) if (a = arguments[d], "function" === typeof a) 0 == d && 1 < e && (b = function() {}, b.prototype = a.prototype, b = new b, a = a.prototype);
else {
a.b && (c = a.init, delete a.init)
}
if (!b || !a) throw Error("You must provide an object to copy from and to");
for (var f in a) b[f] = a[f];
c.prototype = b;
return c
};
(function(c) {
c.Person = __MapNSImpl__.a({
init: function(b) {
this.name = b
},
whatever:function(x){
}
})
})(__MapNS__);
现在,以“人”为例,在编译之后,“人”的所有方法显然都是针对黑客的,即使这些方法也必须暴露出来。
但是我想知道我是否可以像这样编译已编译的代码;
...........
var xx="init",xxx="whatever",xxxx=="Person";
c[xxxx] = __MapNSImpl__.a({
xx: function(b) {
this.name = b
},
xxx:function(x){
}
})
...........
就像谷歌地图的压缩一样。
有什么想法吗?
答案 0 :(得分:2)
您正在寻找的确切答案是通过使用Java API或通过自定义构建编译器来启用编译器中的AliasStrings传递。默认情况下不启用传递,因为在考虑gzip时它会产生更大的代码。
要真正获得与大多数Google产品相同的效果,您需要对代码进行重大更改。
在全局范围内定义对象和方法。在全局声明它们之后将它们分配给名称空间。您可以使用output_wrapper
标志将已编译的代码包装在函数中以防止全局范围冲突。例如:
function a() {}; window['Namespace']['obj'] = a;
直接定义对象 - 不要使用辅助方法。而不是
var a = _NameSpaceInternal_.Class({"init":function(name){ this.name=name; });
你会使用类似的东西:
function a(){}; a.prototype.name = ""; a.prototype.init = function(name) { this.name=name; };
这可以避免使用带引号的语法,并允许编译器重命名您的属性和方法。
有关使用Closure-compiler最佳编译/重命名的编码样式的更多示例,请参阅Closure Library。