问题
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.
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.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 keywordthis
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