17

亲爱的伙计们,Closure Compiler 在高级模式下给出了这个警告,下划线{this.

JSC_USED_GLOBAL_THIS:在第 200 行字符 33 处危险地使用全局 this 对象 hovers[i4].onfocus = function() {this.className += "Hovered";}

JSC_USED_GLOBAL_THIS:在第 201 行字符 32 处危险地使用全局 this 对象 hovers[i4].onblur = function() {this.className = this.className.replace(/Hove...

JSC_USED_GLOBAL_THIS:在第 201 行字符 49 处危险地使用全局 this 对象 hovers[i4].onblur = function() {this.className = this.className.replace(/Hove...

JSC_USED_GLOBAL_THIS:在第 218 行字符 38 处危险地使用全局 this 对象 buttons[i5].onmouseover = function() {this.className += "Hovered";}

Q1。这有什么好危险的?
Q2。我应该改变这个吗?
Q3。如何改进/解决此代码?

谢谢!

4

3 回答 3

18

如果您知道“this”变量的类型,您可以使用 JsDoc 声明它以阻止编译器抱怨:

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

警告:但是,这假设您确定“this”变量的类型。这可能不像看起来那么容易。例如:

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

你会知道 "this" indoSomething指的是foo. 然而,如果你使用闭包编译器的高级模式,编译器可能会“扁平化”foo命名空间,你最终会得到:

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

foo.doSomething“展平”为单个全局变量a。在这种情况下,“this”变量显然指向了全局对象!你的代码会坏掉!

因此,闭包编译器非常坚决地警告您不要在可以展平的函数中使用“this”。您可以在构造函数和原型函数中使用“this”而不会出现此警告。

要解决这个问题,最好通过使用命名空间本身来避免使用“this”:

foo.doSomething = function(x) { foo.bar = x; }
foo.doSomething("Hello");
于 2011-03-21T03:51:57.157 回答
12

“this”在不同的上下文中可能有不同的含义,所以它会准确地告诉你。您可以改用闭包:

代替

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

有:

hovers[i4].onfocus = function(self) 
{
    return function() {self.className += "Hovered";}
}(hovers[i4])
于 2011-03-14T16:34:55.117 回答
8

只是添加@marcinkuzminski 对@stephen Chung 答案添加评论的示例

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

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

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

于 2013-11-13T23:24:19.427 回答