关闭编译器警告`危险使用全局此对象`?

Sam*_*Sam 16 javascript debugging jquery google-closure-compiler

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

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

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

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

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

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

MERCI!

Ste*_*ung 18

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

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

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

foo.doSomething = function(x) { this.bar = x; }
foo.doSomething("Hello");
Run Code Online (Sandbox Code Playgroud)

你会知道"this" doSomething指的是foo.但是,如果您使用Closure Compiler 的高级模式,编译器可能会"展平" foo命名空间,您将最终得到:

a = function(x) { this.b = x }
a("Hello");
Run Code Online (Sandbox Code Playgroud)

foo.doSomething被"展平",以一个单一的全局变量a.在这种情况下,"this"变量显然指向全局对象!你的代码会破裂!

因此,Closure Compiler非常坚定地警告你不要在可以展平的函数中使用"this".您可以在构造函数和原型函数中使用"this",但不会出现此警告.

要解决此问题,最好避免使用命名空间本身来使用"this":

foo.doSomething = function(x) { foo.bar = x; }
foo.doSomething("Hello");
Run Code Online (Sandbox Code Playgroud)

  • 对于定义类的任何函数,你应该使用@constructor来JSDoc来摆脱这个警告.这是Google建议用于此类警告的方式 (5认同)

And*_*rey 12

"this"在不同的上下文中可能有不同的含义,因此它会准确地告诉您.您可以使用闭包:

代替

hovers[i4].onfocus = function() {this.className += "Hovered";}
Run Code Online (Sandbox Code Playgroud)

有:

hovers[i4].onfocus = function(self) 
{
    return function() {self.className += "Hovered";}
}(hovers[i4])
Run Code Online (Sandbox Code Playgroud)

  • "危险地使用这个"并不试图警告用户在不同情况下对"这个"的不同含义.这是一个告诉用户的警告,如果编译器决定*flatten*命名空间,任何使用"this"将指向错误的对象并将破坏代码.这是一个纯粹与编译器执行的优化有关的警告. (17认同)

dek*_*dev 8

只是添加@marcinkuzminski为@stephen Chung回答添加评论的例子

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

  this.data_  = data || {};   /* this gives warning */
};
Run Code Online (Sandbox Code Playgroud)

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