我最近测试了UglifyJS和YUI Compressor并发现了一些奇怪的事 两个minifiers似乎都没有改变对象属性的名称,只改变变量和函数的名称。
例如,如果我有以下代码:
var objName = {first:2, second:4};
alert(objName.first + " " + objName.second);
名称first
和second
在缩小版本中保持不变
那是为什么?
答案 0 :(得分:9)
因为在javascript中,在函数中创建了一个新的作用域,所以您可以将代码置于一个立即调用的函数中。
// scoped
(function() {
var objName = {first:2, second:4};
alert(objName.first + " " + objName.second);
})();
然后使用Google's Closure Compiler,如果您打开“高级”优化,它将看到属性仅在本地使用,并将对它们进行模糊处理。
// result
var a={a:2,b:4};alert(a.a+" "+a.b);
答案 1 :(得分:8)
这是因为它不知道对象的使用位置。它可以在其他代码的外部使用,你不希望你的其他代码在你混淆它时就必须改变。
编辑所以基本上就是这样,可以防止混淆破坏对混淆时可能无法弄清楚的属性的外部/内部引用。
答案 2 :(得分:3)
由于JavaScript中的对象没有明确定义的范围规则,因此无法以保证正确的方式对名称进行模糊处理。
例如,如果您有以下功能:
function f() {
return { first: 'foo', second: 'bar' };
}
为了混淆属性名称,您必须确定调用f
的所有位置。由于函数在JavaScript中是一流的,因此可以以任意方式分配和传递它们,从而无法确定引用f
的位置,而无需实际运行程序。
此外,JavaScript没有任何方法可以指定围绕什么是公共API以及什么不是公共API的意图。即使最小化器可以可靠地确定在你给它的代码中调用函数的位置,也没有办法对代码进行相同的改变。
答案 3 :(得分:2)
我猜这是因为缩小器会破坏对象属性。考虑一下:
function getProp(ob,name) {
return ob[name];
}
var objName = {first: 2, second: 4};
var prop = getProp(objName, "second");
minifier无法知道作为对象属性的字符串文字"second"
。缩小的代码可以看起来像这样:
function a(b,c){return b[c]}var d={p1:2,p2:4};var e=a(d,"second")
现在破了。
答案 4 :(得分:1)
最新版本的uglify(今天)有对象属性损坏,请参阅v2.4.19。它还支持保留文件,用于排除对象属性和不希望损坏的变量。看看吧。
答案 5 :(得分:0)
到目前为止,混淆属性和函数名称(afaik)的唯一公共工具是Closure Compiler的高级模式。有一个很多的限制和限制,但最终结果通常是值得的。
作为传递说明:Dojo Toolkit与高级模式下的Closure Compiler兼容(进行一些小修改) - 可以说是唯一可以完全混淆的大型公共JavaScript库。因此,如果您正在考虑使用混淆来保护您的IP,那么您应该考虑使用Dojo来完成任务。
答案 6 :(得分:0)
做类似的事情:
// scoped
(function() {
var objName = {first:2, second:4};
var vA = 'first';
var vB = 'second';
alert(objName[vA] + " " + objName[vB]);
})();
一旦objName.first和/或objName.second被引用足够多次,这种技术将开始保存字符。我想不出任何不起作用的理由,但我找不到任何能做到这一点的缩小器。