JavaScript中变量的缩减

3
我正在构建一个JavaScript压缩器,目前处于“缩小本地变量”阶段。我一直在将我的压缩器的结果与各种在线压缩器进行比较,并注意到了Dean Edwards' /packer/的一些有趣之处。
让我们以jQuery库的这个片段为例:
(function( window, undefined ) {
  var document = window.document,
      navigator = window.navigator,
      location = window.location;
});

我的压缩机返回以下代码:

(function(a,b){var c=a.document,d=a.navigator,e=a.location});

但是/packer/返回的是这个:
(function(a,b){var c=a.document,navigator=a.navigator,location=a.location});

为什么/packer/在变量列表中第一个变量后面不会缩小变量?这是一个bug还是有其他原因?

乍一看,我的压缩器似乎做得很好,并且会给出更好的最终结果,但是让我们看看jQuery库中的另一个例子:

var jQuery = (function() {

  var jQuery = function( selector, context ) {
      return new jQuery.fn.init( selector, context, rootjQuery );
    },
    // some other vars
    rootjQuery;
    // etc...
});

以下代码片段非常重要,因为变量rootjQuery在定义之前被引用。

在这种情况下,/packer/执行的操作相同,只压缩列表中的第一个变量:

var jQuery=(function(){var c=function(a,b){return new c.fn.init(a,b,rootjQuery)},rootjQuery});

然而,我的压缩器会有些问题,因为虽然在返回语句中没有定义rootjQuery(因为它尚未被定义),但在稍后被定义时会进行压缩。
var jQuery=(function(){var a=function(b,c){return new a.fn.init(b,c,rootjQuery)},b});

当尝试执行代码时,这显然会导致错误。

有没有什么方法可以解决这个问题?看起来 Dean Edwards 注意到了这个问题,所以他通过仅压缩列表中的第一个 var 来绕过它,这样在偶尔出现这种情况时,就不会导致错误。

我尝试单独挑选在定义之前使用的变量并不压缩它们,但这并不简单,因为在这种情况下,rootjQuery 在与其定义的不同范围内使用。在到达它之前,我无法知道它将在哪个范围内定义。


不确定。创建三个var语句(而不是使用逗号)确实会使它们都变小,尽管在副作用方面不应该有任何区别。 - pimvdb
听起来你不能边读边压缩,而是需要在尝试压缩之前先完全了解源文件(以及来自源文件外部的任何全局变量)。不过我看不出为什么你不能压缩 var v1, v2, v3, ... 列表中的第二个、第三个等变量。 - Paul Grime
感谢您对 rootjQuery 参数的评论,这为我节省了一些时间。 - Gerry
1个回答

0

我现在已经修好了我的压缩机。

正如保罗·格莱姆在评论中所说,压缩任何内容之前必须建立所有变量及其作用域的完整列表。

JavaScript允许引用未定义的事物,因此无法避免这种情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接