Google Closure Compiler: How to preserve code that caches “this”?

六眼飞鱼酱① 提交于 2020-01-02 08:03:51

问题


Introduction

I use Google Closure Compiler frequently for compressing my JavaScript files. Now, it seems to compress my code fairly well.

Now, I try to make a habit of storing the this object in a local variable, because this cannot be obfuscated, but a local variable certainly can be obfuscated. However, Google Closure Compiler does not recognize this, and instead removes all instances of the local variable, replacing it with this.

Regarding optimization...

I am well aware that one should avoid pre-optimization when writing code. However, I feel that caching this is acceptable because doing so provides clarity (because this can have many contexts, and referencing it by another name will reduce ambiguity).

Example

The code below is pretty basic, and I understand that it may be poorly written. However, the code will demonstrate exactly the issue which I am facing.

Here is the original source file, before compression:

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

Now here is the compressed source file. Note that the assignment of this to that has been removed.

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

Ideally, I would expect the assignment to that to remain in some form, perhaps something similar to this:

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

Now, the code above hardly saves any bytes, but when working with a much larger script (as I often do), the savings most definitely add up.

Question

In short, how can I prevent the Closure Compiler from removing the that variable in my above script?


回答1:


You are attempting to out-think the compiler. It's a losing battle. However, here's the two main reasons people try to do this type of thing.

  1. Reduce size of code. The theory being that a single letter variable is smaller than the keyword this. However, this theory is flawed in most cases. See the compiler FAQ.

  2. Prevent the context of the keyword this from changing. However, in SIMPLE_OPTIMIZATIONS this is unnecessary. If you create an inner closure that references your variable, the compiler will not inline the value. Under ADVANCED_OPTIMIZATIONS, using the keyword this can be dangerous outside of a prototype function or constructor and should be done with care. See an article explaining why.

If you really want to prevent the compiler from inlining your value, you'll need to add it as a property on an object using quoted syntax:

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



回答2:


I suppose if you really have to you could do this:

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


来源:https://stackoverflow.com/questions/14207380/google-closure-compiler-how-to-preserve-code-that-caches-this

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!