Closure Compiler Warning `dangerous use of the global this object`?

南楼画角 提交于 2019-11-26 20:38:08

问题


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!


回答1:


"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])



回答2:


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");



回答3:


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



来源:https://stackoverflow.com/questions/5301373/closure-compiler-warning-dangerous-use-of-the-global-this-object

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