Closure Compiler Warning `dangerous use of the glo

2020-01-31 03:26发布

Dear folks, Closure Compiler gives this warnings in Advanced Mode, underlining {this.

JSC_USED_GLOBAL_THIS: dangerous use of the global this object at line 200 character 33 hovers[i4].onfocus = function() {this.className += "Hovered";}

JSC_USED_GLOBAL_THIS: dangerous use of the global this object at line 201 character 32 hovers[i4].onblur = function() {this.className = this.className.replace(/Hove...

JSC_USED_GLOBAL_THIS: dangerous use of the global this object at line 201 character 49 hovers[i4].onblur = function() {this.className = this.className.replace(/Hove...

JSC_USED_GLOBAL_THIS: dangerous use of the global this object at line 218 character 38 buttons[i5].onmouseover = function() {this.className += "Hovered";}

Q1. Whats so dangerous about this?
Q2. Should I change this?
Q3. How do I improve/solve this code?

merci!

3条回答
戒情不戒烟
2楼-- · 2020-01-31 03:56

Just to add example of what @marcinkuzminski added comment to @stephen Chung answer

 /**
 * Model for ListBox
 *
 * @constructor <-- add this to remove the warning
 */
MyProject.ListBoxModel = function ( data ){

  this.data_  = data || {};   /* this gives warning */
};

Source : https://developers.google.com/closure/compiler/docs/js-for-compiler

查看更多
我命由我不由天
3楼-- · 2020-01-31 04:04

If you know the type of the "this" variable, you can declare it with a JsDoc to stop the compiler from complaining:

hovers[i4].onfocus = 
/** @this {Element} */
function() {this.className += "Hovered";}

Caveat: this, however, assumes you know for sure the type of the "this" variable. This may not be as easy as it seems. For example:

foo.doSomething = function(x) { this.bar = x; }
foo.doSomething("Hello");

You would have known that "this" in doSomething refers to foo. However, if you use the Advanced Mode of the Closure Compiler, the compiler may "flatten" the foo namespace and you'll end up with:

a = function(x) { this.b = x }
a("Hello");

with foo.doSomething being "flattened" to a single global variable a. In this case, the "this" variable obviously points to the global object instead! Your code will break!

Therefore, the Closure Compiler is quite adamant in warning you not to use "this" in functions that can be flattened. You may use "this" in constructors and prototype functions without this warning though.

To resolve this, it is better to avoid using "this" by using the namespace itself:

foo.doSomething = function(x) { foo.bar = x; }
foo.doSomething("Hello");
查看更多
你好瞎i
4楼-- · 2020-01-31 04:05

"this" might have different meaning in different context, so it tells you exactly that. You can use closures instead:

Instead of

hovers[i4].onfocus = function() {this.className += "Hovered";}

have:

hovers[i4].onfocus = function(self) 
{
    return function() {self.className += "Hovered";}
}(hovers[i4])
查看更多
登录 后发表回答