Google Closure Compiler:如何保留缓存“this”的代码?

3

介绍

我经常使用Google Closure Compiler来压缩我的JavaScript文件。现在,它似乎可以很好地压缩我的代码。

现在,我试图养成一个习惯,将this对象存储在本地变量中,因为this不能被混淆,但是本地变量可以被混淆。然而,Google Closure Compiler却没有识别出这一点,而是删除了所有本地变量的实例,并用this替换。

关于优化...

我非常清楚在编写代码时应该避免过度优化。但是,我认为缓存this是可以接受的,因为这样做可以提供清晰度(因为this可能有许多上下文,用另一个名称引用它将减少歧义)。

示例

下面的代码相当基础,我知道它可能写得不好。但是,这段代码将演示我所面临的问题。

这是压缩之前的原始源文件:

(function() {
  var that = this;
  that.a = 3;
  that.b = 4;
  this.c = 5;
  return that;
}());

现在这里是压缩的源文件。请注意,将this分配给that的任务已被删除。
(function(){this.a=3;this.b=4;this.c=5;return this})();

理想情况下,我希望that的任务能以某种形式保留下来,可能类似于这样:
(function(){var t=this;t.a=3;t.b=4;t.c=5;return t})();

现在,上面的代码几乎没有节省任何字节,但是当使用更大的脚本(我经常这样做)时,节省的字节肯定会累积。

问题

简而言之,我如何防止Closure Compiler从上述脚本中删除that变量?


2
你为什么在意呢?这只是5-10字节的小事,不会影响任何东西,继续前进吧。 - gdoron
好问题,但是为什么在原始源代码中要使用那个变量呢?它只是用来混淆吗? - Bergi
我将this赋给一个变量,因为它能提供清晰度。毕竟,this有许多上下文,所以用另一个名称引用它可以减少歧义。 - caleb531
1
如果您为了清晰度而这样做,那么为什么在优化后它被删除会让您在意呢? - John
你提出了一个很好的观点;我只是有些好奇。如果是那样的话,我就不需要更多的帮助了。谢谢你的解释。;) - caleb531
2个回答

2
你试图超越编译器的思维,但这是一场注定会失败的战斗。然而,人们尝试这样做的主要原因有两个:
  1. 减小代码大小。理论上,单个字母变量比关键字 this 更小。然而,在大多数情况下,这种理论是错误的。请参见编译器常见问题解答

  2. 防止关键字 this 的上下文发生变化。然而,在 SIMPLE_OPTIMIZATIONS 中,这是不必要的。如果您创建一个引用您的变量的内部闭包,编译器将不会内联该值。在 ADVANCED_OPTIMIZATIONS 下,除了原型函数或构造函数外,使用关键字 this 可能是危险的,并且应该谨慎处理。请参见一篇解释原因的文章

如果您真的想防止编译器内联您的值,您需要使用引号语法将其作为对象的属性添加:

(function() {
  var config = {};
  config['that'] = this;
})()

0

我想如果你真的必须这样做,你可以这样:

(function() {
  var that = this || 1;
  that.a = 3;
  that.b = 4;
  this.c = 5;
  return that;
}());

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