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

时间:2011-03-14 16:21:21

标签: javascript jquery debugging 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!

3 个答案:

答案 0 :(得分:18)

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

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

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

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

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

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

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

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

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

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

答案 1 :(得分:12)

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

而不是

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

有:

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

答案 2 :(得分: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